diff options
Diffstat (limited to 'hw/xgl/xglpict.c')
-rw-r--r-- | hw/xgl/xglpict.c | 282 |
1 files changed, 249 insertions, 33 deletions
diff --git a/hw/xgl/xglpict.c b/hw/xgl/xglpict.c index 7bfbcd398..90f1c900e 100644 --- a/hw/xgl/xglpict.c +++ b/hw/xgl/xglpict.c @@ -5,7 +5,7 @@ * 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 names of + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,10 +20,11 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman <davidr@freedesktop.org> + * Author: David Reveman <davidr@novell.com> */ #include "xgl.h" +#include "fb.h" #ifdef RENDER @@ -33,7 +34,7 @@ #define XGL_PICTURE_FALLBACK_EPILOGUE(pPicture, func, xglfunc) \ XGL_PICTURE_SCREEN_WRAP (func, xglfunc); \ - xglAddSurfaceDamage (pPicture->pDrawable) + xglAddCurrentSurfaceDamage (pPicture->pDrawable) void xglComposite (CARD8 op, @@ -49,7 +50,7 @@ xglComposite (CARD8 op, CARD16 width, CARD16 height) { - PictureScreenPtr pPictureScreen; + PictureScreenPtr pPictureScreen; ScreenPtr pScreen = pDst->pDrawable->pScreen; XGL_SCREEN_PRIV (pScreen); @@ -58,9 +59,13 @@ xglComposite (CARD8 op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, - xDst, yDst, - width, height)) + xDst + pDst->pDrawable->x, yDst + pDst->pDrawable->y, + width, height, + NULL, NULL)) + { + xglAddCurrentBitDamage (pDst->pDrawable); return; + } pPictureScreen = GetPictureScreen (pScreen); @@ -73,46 +78,74 @@ xglComposite (CARD8 op, FatalError (XGL_SW_FAILURE_STRING); } - XGL_PICTURE_FALLBACK_PROLOGUE (pDst, Composite); + if (op == PictOpSrc) + { + XGL_DRAWABLE_PIXMAP (pDst->pDrawable); + + if (!xglMapPixmapBits (pPixmap)) + FatalError (XGL_SW_FAILURE_STRING); + } else + xglSyncDamageBoxBits (pDst->pDrawable); + + XGL_PICTURE_SCREEN_UNWRAP (Composite); (*pPictureScreen->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); - XGL_PICTURE_FALLBACK_EPILOGUE (pDst, Composite, xglComposite); -} + XGL_PICTURE_SCREEN_WRAP (Composite, xglComposite); -void -xglGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr list, - GlyphPtr *glyphs) -{ - miGlyphs (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); + if (op == PictOpSrc) + { + RegionRec region; + + xDst += pDst->pDrawable->x; + yDst += pDst->pDrawable->y; + + xSrc += pSrc->pDrawable->x; + ySrc += pSrc->pDrawable->y; + + if (pMask) + { + xMask += pMask->pDrawable->x; + yMask += pMask->pDrawable->y; + } + + if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, + xSrc, ySrc, xMask, yMask, xDst, yDst, + width, height)) + return; + + xglAddSurfaceDamage (pDst->pDrawable, ®ion); + REGION_UNINIT (pDst->pDrawable->pScreen, ®ion); + } else + xglAddCurrentSurfaceDamage (pDst->pDrawable); } void -xglRasterizeTrapezoid (PicturePtr pDst, - xTrapezoid *trap, - int xOff, - int yOff) +xglAddTriangles (PicturePtr pDst, + INT16 xOff, + INT16 yOff, + int ntri, + xTriangle *tris) { PictureScreenPtr pPictureScreen; ScreenPtr pScreen = pDst->pDrawable->pScreen; XGL_SCREEN_PRIV (pScreen); + XGL_DRAWABLE_PIXMAP_PRIV (pDst->pDrawable); pPictureScreen = GetPictureScreen (pScreen); - XGL_PICTURE_FALLBACK_PROLOGUE (pDst, RasterizeTrapezoid); - (*pPictureScreen->RasterizeTrapezoid) (pDst, trap, xOff, yOff); - XGL_PICTURE_FALLBACK_EPILOGUE (pDst, RasterizeTrapezoid, - xglRasterizeTrapezoid); + pPixmapPriv->damageBox.x1 = 0; + pPixmapPriv->damageBox.y1 = 0; + pPixmapPriv->damageBox.x2 = pDst->pDrawable->width; + pPixmapPriv->damageBox.y2 = pDst->pDrawable->height; + + XGL_PICTURE_FALLBACK_PROLOGUE (pDst, AddTriangles); + (*pPictureScreen->AddTriangles) (pDst, xOff, yOff, ntri, tris); + XGL_PICTURE_FALLBACK_EPILOGUE (pDst, AddTriangles, xglAddTriangles); } + void xglChangePicture (PicturePtr pPicture, Mask mask) @@ -207,16 +240,18 @@ xglUpdatePicture (PicturePtr pPicture) case PictFilterNearest: case PictFilterFast: glitz_surface_set_filter (surface, GLITZ_FILTER_NEAREST, NULL, 0); - pPixmapPriv->pictureMask &= ~xglPFFilterMask; break; case PictFilterGood: case PictFilterBest: case PictFilterBilinear: glitz_surface_set_filter (surface, GLITZ_FILTER_BILINEAR, NULL, 0); - pPixmapPriv->pictureMask &= ~xglPFFilterMask; break; - default: - pPixmapPriv->pictureMask |= xglPFFilterMask; + case PictFilterConvolution: + glitz_surface_set_filter (surface, GLITZ_FILTER_CONVOLUTION, + (glitz_fixed16_16_t *) + pPicture->filter_params, + pPicture->filter_nparams); + break; } } @@ -237,4 +272,185 @@ xglUpdatePicture (PicturePtr pPicture) pPixmapPriv->pictureMask &= ~XGL_PICTURE_CHANGES (~0); } +static int +xglVisualDepth (ScreenPtr pScreen, VisualPtr pVisual) +{ + DepthPtr pDepth; + int d, v; + + for (d = 0; d < pScreen->numDepths; d++) + { + pDepth = &pScreen->allowedDepths[d]; + for (v = 0; v < pDepth->numVids; v++) + if (pDepth->vids[v] == pVisual->vid) + return pDepth->depth; + } + + return 0; +} + +typedef struct _xglformatInit { + CARD32 format; + CARD8 depth; +} xglFormatInitRec, *xglFormatInitPtr; + +static int +xglAddFormat (xglFormatInitPtr formats, + int nformat, + CARD32 format, + CARD8 depth) +{ + int n; + + for (n = 0; n < nformat; n++) + if (formats[n].format == format && formats[n].depth == depth) + return nformat; + + formats[nformat].format = format; + formats[nformat].depth = depth; + + return ++nformat; +} + +#define Mask(n) ((n) == 32 ? 0xffffffff : ((1 << (n)) - 1)) + +Bool +xglPictureInit (ScreenPtr pScreen) +{ + int f, nformats = 0; + PictFormatPtr pFormats; + xglFormatInitRec formats[64]; + CARD32 format; + CARD8 depth; + VisualPtr pVisual; + int v; + int bpp; + int r, g, b; + int d; + DepthPtr pDepth; + + /* formats required by protocol */ + formats[nformats].format = PICT_a1; + formats[nformats].depth = 1; + nformats++; + formats[nformats].format = PICT_a4; + formats[nformats].depth = 4; + nformats++; + formats[nformats].format = PICT_a8; + formats[nformats].depth = 8; + nformats++; + formats[nformats].format = PICT_a8r8g8b8; + formats[nformats].depth = 32; + nformats++; + + /* now look through the depths and visuals adding other formats */ + for (v = 0; v < pScreen->numVisuals; v++) + { + pVisual = &pScreen->visuals[v]; + depth = xglVisualDepth (pScreen, pVisual); + if (!depth) + continue; + + bpp = BitsPerPixel (depth); + switch (pVisual->class) { + case DirectColor: + case TrueColor: + r = Ones (pVisual->redMask); + g = Ones (pVisual->greenMask); + b = Ones (pVisual->blueMask); + if (pVisual->offsetBlue == 0 && + pVisual->offsetGreen == b && + pVisual->offsetRed == b + g) + { + format = PICT_FORMAT (bpp, PICT_TYPE_ARGB, 0, r, g, b); + nformats = xglAddFormat (formats, nformats, format, depth); + } + break; + case StaticColor: + case PseudoColor: + case StaticGray: + case GrayScale: + break; + } + } + + /* walk supported depths and add missing Direct formats */ + for (d = 0; d < pScreen->numDepths; d++) + { + pDepth = &pScreen->allowedDepths[d]; + bpp = BitsPerPixel (pDepth->depth); + format = 0; + switch (bpp) { + case 16: + if (pDepth->depth == 15) + nformats = xglAddFormat (formats, nformats, + PICT_x1r5g5b5, pDepth->depth); + if (pDepth->depth == 16) + nformats = xglAddFormat (formats, nformats, + PICT_r5g6b5, pDepth->depth); + break; + case 24: + if (pDepth->depth == 24) + nformats = xglAddFormat (formats, nformats, + PICT_r8g8b8, pDepth->depth); + break; + case 32: + if (pDepth->depth == 24) + nformats = xglAddFormat (formats, nformats, + PICT_x8r8g8b8, pDepth->depth); + break; + } + } + + pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec)); + if (!pFormats) + return 0; + + memset (pFormats, '\0', nformats * sizeof (PictFormatRec)); + for (f = 0; f < nformats; f++) + { + pFormats[f].id = FakeClientID (0); + pFormats[f].depth = formats[f].depth; + format = formats[f].format; + pFormats[f].format = format; + pFormats[f].type = PictTypeDirect; + switch (PICT_FORMAT_TYPE (format)) { + case PICT_TYPE_ARGB: + pFormats[f].direct.alphaMask = Mask (PICT_FORMAT_A (format)); + if (pFormats[f].direct.alphaMask) + pFormats[f].direct.alpha = (PICT_FORMAT_R (format) + + PICT_FORMAT_G (format) + + PICT_FORMAT_B (format)); + + pFormats[f].direct.redMask = Mask (PICT_FORMAT_R (format)); + pFormats[f].direct.red = (PICT_FORMAT_G (format) + + PICT_FORMAT_B (format)); + + pFormats[f].direct.greenMask = Mask (PICT_FORMAT_G (format)); + pFormats[f].direct.green = PICT_FORMAT_B (format); + + pFormats[f].direct.blueMask = Mask (PICT_FORMAT_B (format)); + pFormats[f].direct.blue = 0; + break; + case PICT_TYPE_A: + pFormats[f].direct.alpha = 0; + pFormats[f].direct.alphaMask = Mask (PICT_FORMAT_A (format)); + break; + case PICT_TYPE_COLOR: + case PICT_TYPE_GRAY: + break; + } + } + + if (!fbPictureInit (pScreen, pFormats, nformats)) + return FALSE; + + if (PictureAddFilter (pScreen, + FilterConvolution, + miFilterValidateParams) < 0) + return FALSE; + + return TRUE; +} + #endif |