diff options
Diffstat (limited to 'exa/exa_render.c')
-rw-r--r-- | exa/exa_render.c | 1463 |
1 files changed, 716 insertions, 747 deletions
diff --git a/exa/exa_render.c b/exa/exa_render.c index 3974afe87..172e2b56d 100644 --- a/exa/exa_render.c +++ b/exa/exa_render.c @@ -33,7 +33,8 @@ #include "mipict.h" #if DEBUG_TRACE_FALL -static void exaCompositeFallbackPictDesc(PicturePtr pict, char *string, int n) +static void +exaCompositeFallbackPictDesc(PicturePtr pict, char *string, int n) { char format[20]; char size[20]; @@ -41,76 +42,73 @@ static void exaCompositeFallbackPictDesc(PicturePtr pict, char *string, int n) int temp; if (!pict) { - snprintf(string, n, "None"); - return; + snprintf(string, n, "None"); + return; } - switch (pict->format) - { + switch (pict->format) { case PICT_a8r8g8b8: - snprintf(format, 20, "ARGB8888"); - break; + snprintf(format, 20, "ARGB8888"); + break; case PICT_x8r8g8b8: - snprintf(format, 20, "XRGB8888"); - break; + snprintf(format, 20, "XRGB8888"); + break; case PICT_b8g8r8a8: - snprintf(format, 20, "BGRA8888"); - break; + snprintf(format, 20, "BGRA8888"); + break; case PICT_b8g8r8x8: - snprintf(format, 20, "BGRX8888"); - break; + snprintf(format, 20, "BGRX8888"); + break; case PICT_r5g6b5: - snprintf(format, 20, "RGB565 "); - break; + snprintf(format, 20, "RGB565 "); + break; case PICT_x1r5g5b5: - snprintf(format, 20, "RGB555 "); - break; + snprintf(format, 20, "RGB555 "); + break; case PICT_a8: - snprintf(format, 20, "A8 "); - break; + snprintf(format, 20, "A8 "); + break; case PICT_a1: - snprintf(format, 20, "A1 "); - break; + snprintf(format, 20, "A1 "); + break; default: - snprintf(format, 20, "0x%x", (int)pict->format); - break; + snprintf(format, 20, "0x%x", (int) pict->format); + break; } if (pict->pDrawable) { - loc = exaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm'; + loc = exaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm'; - snprintf(size, 20, "%dx%d%s", pict->pDrawable->width, - pict->pDrawable->height, pict->repeat ? - " R" : ""); - } else { - loc = '-'; + snprintf(size, 20, "%dx%d%s", pict->pDrawable->width, + pict->pDrawable->height, pict->repeat ? " R" : ""); + } + else { + loc = '-'; - snprintf(size, 20, "%s", pict->repeat ? " R" : ""); + snprintf(size, 20, "%s", pict->repeat ? " R" : ""); } - snprintf(string, n, "%p:%c fmt %s (%s)", pict->pDrawable, loc, format, size); + snprintf(string, n, "%p:%c fmt %s (%s)", pict->pDrawable, loc, format, + size); } static void exaPrintCompositeFallback(CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst) + PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst) { char sop[20]; char srcdesc[40], maskdesc[40], dstdesc[40]; - switch(op) - { + switch (op) { case PictOpSrc: - snprintf(sop, sizeof(sop), "Src"); - break; + snprintf(sop, sizeof(sop), "Src"); + break; case PictOpOver: - snprintf(sop, sizeof(sop), "Over"); - break; + snprintf(sop, sizeof(sop), "Over"); + break; default: - snprintf(sop, sizeof(sop), "0x%x", (int)op); - break; + snprintf(sop, sizeof(sop), "0x%x", (int) op); + break; } exaCompositeFallbackPictDesc(pSrc, srcdesc, 40); @@ -118,15 +116,14 @@ exaPrintCompositeFallback(CARD8 op, exaCompositeFallbackPictDesc(pDst, dstdesc, 40); ErrorF("Composite fallback: op %s, \n" - " src %s, \n" - " mask %s, \n" - " dst %s, \n", - sop, srcdesc, maskdesc, dstdesc); + " src %s, \n" + " mask %s, \n" + " dst %s, \n", sop, srcdesc, maskdesc, dstdesc); } -#endif /* DEBUG_TRACE_FALL */ +#endif /* DEBUG_TRACE_FALL */ Bool -exaOpReadsDestination (CARD8 op) +exaOpReadsDestination(CARD8 op) { /* FALSE (does not read destination) is the list of ops in the protocol * document with "0" in the "Fb" column and no "Ab" in the "Fa" column. @@ -136,20 +133,17 @@ exaOpReadsDestination (CARD8 op) switch (op) { case PictOpClear: case PictOpSrc: - return FALSE; + return FALSE; default: - return TRUE; + return TRUE; } } - static Bool -exaGetPixelFromRGBA(CARD32 *pixel, - CARD16 red, - CARD16 green, - CARD16 blue, - CARD16 alpha, - PictFormatPtr pFormat) +exaGetPixelFromRGBA(CARD32 *pixel, + CARD16 red, + CARD16 green, + CARD16 blue, CARD16 alpha, PictFormatPtr pFormat) { int rbits, bbits, gbits, abits; int rshift, bshift, gshift, ashift; @@ -157,8 +151,8 @@ exaGetPixelFromRGBA(CARD32 *pixel, *pixel = 0; if (!PICT_FORMAT_COLOR(pFormat->format) && - PICT_FORMAT_TYPE(pFormat->format) != PICT_TYPE_A) - return FALSE; + PICT_FORMAT_TYPE(pFormat->format) != PICT_TYPE_A) + return FALSE; rbits = PICT_FORMAT_R(pFormat->format); gbits = PICT_FORMAT_G(pFormat->format); @@ -170,28 +164,27 @@ exaGetPixelFromRGBA(CARD32 *pixel, bshift = pFormat->direct.blue; ashift = pFormat->direct.alpha; - *pixel |= ( blue >> (16 - bbits)) << bshift; - *pixel |= ( red >> (16 - rbits)) << rshift; - *pixel |= (green >> (16 - gbits)) << gshift; - *pixel |= (alpha >> (16 - abits)) << ashift; + *pixel |= (blue >> (16 - bbits)) << bshift; + *pixel |= (red >> (16 - rbits)) << rshift; + *pixel |= (green >> (16 - gbits)) << gshift; + *pixel |= (alpha >> (16 - abits)) << ashift; return TRUE; } static Bool -exaGetRGBAFromPixel(CARD32 pixel, - CARD16 *red, - CARD16 *green, - CARD16 *blue, - CARD16 *alpha, - PictFormatPtr pFormat, - PictFormatShort format) +exaGetRGBAFromPixel(CARD32 pixel, + CARD16 *red, + CARD16 *green, + CARD16 *blue, + CARD16 *alpha, + PictFormatPtr pFormat, PictFormatShort format) { int rbits, bbits, gbits, abits; int rshift, bshift, gshift, ashift; if (!PICT_FORMAT_COLOR(format) && PICT_FORMAT_TYPE(format) != PICT_TYPE_A) - return FALSE; + return FALSE; rbits = PICT_FORMAT_R(format); gbits = PICT_FORMAT_G(format); @@ -199,66 +192,67 @@ exaGetRGBAFromPixel(CARD32 pixel, abits = PICT_FORMAT_A(format); if (pFormat) { - rshift = pFormat->direct.red; - gshift = pFormat->direct.green; - bshift = pFormat->direct.blue; - ashift = pFormat->direct.alpha; - } else if (format == PICT_a8r8g8b8) { - rshift = 16; - gshift = 8; - bshift = 0; - ashift = 24; - } else - FatalError("EXA bug: exaGetRGBAFromPixel() doesn't match " - "createSourcePicture()\n"); + rshift = pFormat->direct.red; + gshift = pFormat->direct.green; + bshift = pFormat->direct.blue; + ashift = pFormat->direct.alpha; + } + else if (format == PICT_a8r8g8b8) { + rshift = 16; + gshift = 8; + bshift = 0; + ashift = 24; + } + else + FatalError("EXA bug: exaGetRGBAFromPixel() doesn't match " + "createSourcePicture()\n"); if (rbits) { - *red = ((pixel >> rshift ) & ((1 << rbits) - 1)) << (16 - rbits); - while (rbits < 16) { - *red |= *red >> rbits; - rbits <<= 1; - } - - *green = ((pixel >> gshift ) & ((1 << gbits) - 1)) << (16 - gbits); - while (gbits < 16) { - *green |= *green >> gbits; - gbits <<= 1; - } - - *blue = ((pixel >> bshift ) & ((1 << bbits) - 1)) << (16 - bbits); - while (bbits < 16) { - *blue |= *blue >> bbits; - bbits <<= 1; - } - } else { - *red = 0x0000; - *green = 0x0000; - *blue = 0x0000; + *red = ((pixel >> rshift) & ((1 << rbits) - 1)) << (16 - rbits); + while (rbits < 16) { + *red |= *red >> rbits; + rbits <<= 1; + } + + *green = ((pixel >> gshift) & ((1 << gbits) - 1)) << (16 - gbits); + while (gbits < 16) { + *green |= *green >> gbits; + gbits <<= 1; + } + + *blue = ((pixel >> bshift) & ((1 << bbits) - 1)) << (16 - bbits); + while (bbits < 16) { + *blue |= *blue >> bbits; + bbits <<= 1; + } + } + else { + *red = 0x0000; + *green = 0x0000; + *blue = 0x0000; } if (abits) { - *alpha = ((pixel >> ashift ) & ((1 << abits) - 1)) << (16 - abits); - while (abits < 16) { - *alpha |= *alpha >> abits; - abits <<= 1; - } - } else - *alpha = 0xffff; + *alpha = ((pixel >> ashift) & ((1 << abits) - 1)) << (16 - abits); + while (abits < 16) { + *alpha |= *alpha >> abits; + abits <<= 1; + } + } + else + *alpha = 0xffff; return TRUE; } static int -exaTryDriverSolidFill(PicturePtr pSrc, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height) +exaTryDriverSolidFill(PicturePtr pSrc, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { - ExaScreenPriv (pDst->pDrawable->pScreen); + ExaScreenPriv(pDst->pDrawable->pScreen); RegionRec region; BoxPtr pbox; int nbox; @@ -268,75 +262,71 @@ exaTryDriverSolidFill(PicturePtr pSrc, CARD32 pixel; CARD16 red, green, blue, alpha; - pDstPix = exaGetDrawablePixmap (pDst->pDrawable); + pDstPix = exaGetDrawablePixmap(pDst->pDrawable); pDstExaPix = ExaGetPixmapPriv(pDstPix); /* Check whether the accelerator can use the destination pixmap. */ - if (pDstExaPix->accel_blocked) - { - return -1; + if (pDstExaPix->accel_blocked) { + return -1; } xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; if (pSrc->pDrawable) { - xSrc += pSrc->pDrawable->x; - ySrc += pSrc->pDrawable->y; + xSrc += pSrc->pDrawable->x; + ySrc += pSrc->pDrawable->y; } - if (!miComputeCompositeRegion (®ion, pSrc, NULL, pDst, - xSrc, ySrc, 0, 0, xDst, yDst, - width, height)) - return 1; + if (!miComputeCompositeRegion(®ion, pSrc, NULL, pDst, + xSrc, ySrc, 0, 0, xDst, yDst, width, height)) + return 1; - exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y); + exaGetDrawableDeltas(pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y); RegionTranslate(®ion, dst_off_x, dst_off_y); if (pSrc->pDrawable) { - pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable); - pixel = exaGetPixmapFirstPixel (pSrcPix); - } else - pixel = pSrc->pSourcePict->solidFill.color; + pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); + pixel = exaGetPixmapFirstPixel(pSrcPix); + } + else + pixel = pSrc->pSourcePict->solidFill.color; if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha, - pSrc->pFormat, pSrc->format) || - !exaGetPixelFromRGBA(&pixel, red, green, blue, alpha, - pDst->pFormat)) - { - RegionUninit(®ion); - return -1; + pSrc->pFormat, pSrc->format) || + !exaGetPixelFromRGBA(&pixel, red, green, blue, alpha, pDst->pFormat)) { + RegionUninit(®ion); + return -1; } if (pExaScr->do_migration) { - ExaMigrationRec pixmaps[1]; + ExaMigrationRec pixmaps[1]; - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = FALSE; - pixmaps[0].pPix = pDstPix; - pixmaps[0].pReg = ®ion; - exaDoMigration(pixmaps, 1, TRUE); + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = FALSE; + pixmaps[0].pPix = pDstPix; + pixmaps[0].pReg = ®ion; + exaDoMigration(pixmaps, 1, TRUE); } if (!exaPixmapHasGpuCopy(pDstPix)) { - RegionUninit(®ion); - return 0; + RegionUninit(®ion); + return 0; } - if (!(*pExaScr->info->PrepareSolid) (pDstPix, GXcopy, 0xffffffff, pixel)) - { - RegionUninit(®ion); - return -1; + if (!(*pExaScr->info->PrepareSolid) (pDstPix, GXcopy, 0xffffffff, pixel)) { + RegionUninit(®ion); + return -1; } nbox = RegionNumRects(®ion); pbox = RegionRects(®ion); - while (nbox--) - { - (*pExaScr->info->Solid) (pDstPix, pbox->x1, pbox->y1, pbox->x2, pbox->y2); - pbox++; + while (nbox--) { + (*pExaScr->info->Solid) (pDstPix, pbox->x1, pbox->y1, pbox->x2, + pbox->y2); + pbox++; } (*pExaScr->info->DoneSolid) (pDstPix); @@ -347,30 +337,29 @@ exaTryDriverSolidFill(PicturePtr pSrc, } static int -exaTryDriverCompositeRects(CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - int nrect, - ExaCompositeRectPtr rects) +exaTryDriverCompositeRects(CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + int nrect, ExaCompositeRectPtr rects) { - ExaScreenPriv (pDst->pDrawable->pScreen); + ExaScreenPriv(pDst->pDrawable->pScreen); int src_off_x = 0, src_off_y = 0, mask_off_x = 0, mask_off_y = 0; int dst_off_x, dst_off_y; PixmapPtr pSrcPix = NULL, pMaskPix = NULL, pDstPix; ExaPixmapPrivPtr pSrcExaPix = NULL, pMaskExaPix = NULL, pDstExaPix; if (!pExaScr->info->PrepareComposite) - return -1; + return -1; if (pSrc->pDrawable) { - pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); - pSrcExaPix = ExaGetPixmapPriv(pSrcPix); + pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); + pSrcExaPix = ExaGetPixmapPriv(pSrcPix); } if (pMask && pMask->pDrawable) { - pMaskPix = exaGetDrawablePixmap(pMask->pDrawable); - pMaskExaPix = ExaGetPixmapPriv(pMaskPix); + pMaskPix = exaGetDrawablePixmap(pMask->pDrawable); + pMaskExaPix = ExaGetPixmapPriv(pMaskPix); } pDstPix = exaGetDrawablePixmap(pDst->pDrawable); @@ -381,122 +370,120 @@ exaTryDriverCompositeRects(CARD8 op, * happens within limits. */ if (pDstExaPix->accel_blocked || - (pSrcExaPix && pSrcExaPix->accel_blocked) || - (pMaskExaPix && pMaskExaPix->accel_blocked)) - { - return -1; + (pSrcExaPix && pSrcExaPix->accel_blocked) || + (pMaskExaPix && pMaskExaPix->accel_blocked)) { + return -1; } if (pExaScr->info->CheckComposite && - !(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst)) - { - return -1; + !(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst)) { + return -1; } if (pExaScr->do_migration) { - ExaMigrationRec pixmaps[3]; - int i = 0; - - pixmaps[i].as_dst = TRUE; - pixmaps[i].as_src = exaOpReadsDestination(op); - pixmaps[i].pPix = pDstPix; - pixmaps[i].pReg = NULL; - i++; - - if (pSrcPix) { - pixmaps[i].as_dst = FALSE; - pixmaps[i].as_src = TRUE; - pixmaps[i].pPix = pSrcPix; - pixmaps[i].pReg = NULL; - i++; - } - - if (pMaskPix) { - pixmaps[i].as_dst = FALSE; - pixmaps[i].as_src = TRUE; - pixmaps[i].pPix = pMaskPix; - pixmaps[i].pReg = NULL; - i++; - } - - exaDoMigration(pixmaps, i, TRUE); + ExaMigrationRec pixmaps[3]; + int i = 0; + + pixmaps[i].as_dst = TRUE; + pixmaps[i].as_src = exaOpReadsDestination(op); + pixmaps[i].pPix = pDstPix; + pixmaps[i].pReg = NULL; + i++; + + if (pSrcPix) { + pixmaps[i].as_dst = FALSE; + pixmaps[i].as_src = TRUE; + pixmaps[i].pPix = pSrcPix; + pixmaps[i].pReg = NULL; + i++; + } + + if (pMaskPix) { + pixmaps[i].as_dst = FALSE; + pixmaps[i].as_src = TRUE; + pixmaps[i].pPix = pMaskPix; + pixmaps[i].pReg = NULL; + i++; + } + + exaDoMigration(pixmaps, i, TRUE); } - pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y); + pDstPix = exaGetOffscreenPixmap(pDst->pDrawable, &dst_off_x, &dst_off_y); if (!pDstPix) - return 0; + return 0; if (pSrcPix) { - pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y); - if (!pSrcPix) - return 0; + pSrcPix = + exaGetOffscreenPixmap(pSrc->pDrawable, &src_off_x, &src_off_y); + if (!pSrcPix) + return 0; } if (pMaskPix) { - pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x, &mask_off_y); - if (!pMaskPix) - return 0; + pMaskPix = + exaGetOffscreenPixmap(pMask->pDrawable, &mask_off_x, &mask_off_y); + if (!pMaskPix) + return 0; } if (!(*pExaScr->info->PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix, - pMaskPix, pDstPix)) - return -1; - - while (nrect--) - { - INT16 xDst = rects->xDst + pDst->pDrawable->x; - INT16 yDst = rects->yDst + pDst->pDrawable->y; - INT16 xMask = rects->xMask; - INT16 yMask = rects->yMask; - INT16 xSrc = rects->xSrc; - INT16 ySrc = rects->ySrc; - RegionRec region; - BoxPtr pbox; - int nbox; - - if (pMaskPix) { - xMask += pMask->pDrawable->x; - yMask += pMask->pDrawable->y; - } - - if (pSrcPix) { - xSrc += pSrc->pDrawable->x; - ySrc += pSrc->pDrawable->y; - } - - if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, - xSrc, ySrc, xMask, yMask, xDst, yDst, - rects->width, rects->height)) - goto next_rect; - - RegionTranslate(®ion, dst_off_x, dst_off_y); - - nbox = RegionNumRects(®ion); - pbox = RegionRects(®ion); - - xMask = xMask + mask_off_x - xDst - dst_off_x; - yMask = yMask + mask_off_y - yDst - dst_off_y; - xSrc = xSrc + src_off_x - xDst - dst_off_x; - ySrc = ySrc + src_off_y - yDst - dst_off_y; - - while (nbox--) - { - (*pExaScr->info->Composite) (pDstPix, - pbox->x1 + xSrc, - pbox->y1 + ySrc, - pbox->x1 + xMask, - pbox->y1 + yMask, - pbox->x1, - pbox->y1, - pbox->x2 - pbox->x1, - pbox->y2 - pbox->y1); - pbox++; - } - - next_rect: - RegionUninit(®ion); - - rects++; + pMaskPix, pDstPix)) + return -1; + + while (nrect--) { + INT16 xDst = rects->xDst + pDst->pDrawable->x; + INT16 yDst = rects->yDst + pDst->pDrawable->y; + INT16 xMask = rects->xMask; + INT16 yMask = rects->yMask; + INT16 xSrc = rects->xSrc; + INT16 ySrc = rects->ySrc; + RegionRec region; + BoxPtr pbox; + int nbox; + + if (pMaskPix) { + xMask += pMask->pDrawable->x; + yMask += pMask->pDrawable->y; + } + + if (pSrcPix) { + xSrc += pSrc->pDrawable->x; + ySrc += pSrc->pDrawable->y; + } + + if (!miComputeCompositeRegion(®ion, pSrc, pMask, pDst, + xSrc, ySrc, xMask, yMask, xDst, yDst, + rects->width, rects->height)) + goto next_rect; + + RegionTranslate(®ion, dst_off_x, dst_off_y); + + nbox = RegionNumRects(®ion); + pbox = RegionRects(®ion); + + xMask = xMask + mask_off_x - xDst - dst_off_x; + yMask = yMask + mask_off_y - yDst - dst_off_y; + xSrc = xSrc + src_off_x - xDst - dst_off_x; + ySrc = ySrc + src_off_y - yDst - dst_off_y; + + while (nbox--) { + (*pExaScr->info->Composite) (pDstPix, + pbox->x1 + xSrc, + pbox->y1 + ySrc, + pbox->x1 + xMask, + pbox->y1 + yMask, + pbox->x1, + pbox->y1, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + pbox++; + } + + next_rect: + RegionUninit(®ion); + + rects++; } (*pExaScr->info->DoneComposite) (pDstPix); @@ -513,14 +500,12 @@ exaTryDriverCompositeRects(CARD8 op, * software. */ void -exaCompositeRects(CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - int nrect, - ExaCompositeRectPtr rects) +exaCompositeRects(CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, int nrect, ExaCompositeRectPtr rects) { - ExaScreenPriv (pDst->pDrawable->pScreen); + ExaScreenPriv(pDst->pDrawable->pScreen); int n; ExaCompositeRectPtr r; int ret; @@ -529,123 +514,125 @@ exaCompositeRects(CARD8 op, * destination directly, so the damage layer takes care of this. */ if (!pMask) { - RegionRec region; - int x1 = MAXSHORT; - int y1 = MAXSHORT; - int x2 = MINSHORT; - int y2 = MINSHORT; - BoxRec box; - - /* We have to manage the damage ourselves, since CompositeRects isn't - * something in the screen that can be managed by the damage extension, - * and EXA depends on damage to track what needs to be migrated between - * the gpu and the cpu. - */ - - /* Compute the overall extents of the composited region - we're making - * the assumption here that we are compositing a bunch of glyphs that - * cluster closely together and damaging each glyph individually would - * be a loss compared to damaging the bounding box. - */ - n = nrect; - r = rects; - while (n--) { - int rect_x2 = r->xDst + r->width; - int rect_y2 = r->yDst + r->height; - - if (r->xDst < x1) x1 = r->xDst; - if (r->yDst < y1) y1 = r->yDst; - if (rect_x2 > x2) x2 = rect_x2; - if (rect_y2 > y2) y2 = rect_y2; - - r++; - } - - if (x2 <= x1 || y2 <= y1) - return; - - box.x1 = x1; - box.x2 = x2 < MAXSHORT ? x2 : MAXSHORT; - box.y1 = y1; - box.y2 = y2 < MAXSHORT ? y2 : MAXSHORT; - - /* The pixmap migration code relies on pendingDamage indicating - * the bounds of the current rendering, so we need to force - * the actual damage into that region before we do anything, and - * (see use of DamagePendingRegion in exaCopyDirty) - */ - - RegionInit(®ion, &box, 1); - - DamageRegionAppend(pDst->pDrawable, ®ion); - - RegionUninit(®ion); + RegionRec region; + int x1 = MAXSHORT; + int y1 = MAXSHORT; + int x2 = MINSHORT; + int y2 = MINSHORT; + BoxRec box; + + /* We have to manage the damage ourselves, since CompositeRects isn't + * something in the screen that can be managed by the damage extension, + * and EXA depends on damage to track what needs to be migrated between + * the gpu and the cpu. + */ + + /* Compute the overall extents of the composited region - we're making + * the assumption here that we are compositing a bunch of glyphs that + * cluster closely together and damaging each glyph individually would + * be a loss compared to damaging the bounding box. + */ + n = nrect; + r = rects; + while (n--) { + int rect_x2 = r->xDst + r->width; + int rect_y2 = r->yDst + r->height; + + if (r->xDst < x1) + x1 = r->xDst; + if (r->yDst < y1) + y1 = r->yDst; + if (rect_x2 > x2) + x2 = rect_x2; + if (rect_y2 > y2) + y2 = rect_y2; + + r++; + } + + if (x2 <= x1 || y2 <= y1) + return; + + box.x1 = x1; + box.x2 = x2 < MAXSHORT ? x2 : MAXSHORT; + box.y1 = y1; + box.y2 = y2 < MAXSHORT ? y2 : MAXSHORT; + + /* The pixmap migration code relies on pendingDamage indicating + * the bounds of the current rendering, so we need to force + * the actual damage into that region before we do anything, and + * (see use of DamagePendingRegion in exaCopyDirty) + */ + + RegionInit(®ion, &box, 1); + + DamageRegionAppend(pDst->pDrawable, ®ion); + + RegionUninit(®ion); } - + /************************************************************/ - - ValidatePicture (pSrc); + + ValidatePicture(pSrc); if (pMask) - ValidatePicture (pMask); - ValidatePicture (pDst); + ValidatePicture(pMask); + ValidatePicture(pDst); ret = exaTryDriverCompositeRects(op, pSrc, pMask, pDst, nrect, rects); if (ret != 1) { - if (ret == -1 && op == PictOpOver && pMask && pMask->componentAlpha && - (!pExaScr->info->CheckComposite || - ((*pExaScr->info->CheckComposite)(PictOpOutReverse, pSrc, pMask, - pDst) && - (*pExaScr->info->CheckComposite)(PictOpAdd, pSrc, pMask, pDst)))) { - ret = exaTryDriverCompositeRects(PictOpOutReverse, pSrc, pMask, - pDst, nrect, rects); - if (ret == 1) { - op = PictOpAdd; - ret = exaTryDriverCompositeRects(op, pSrc, pMask, pDst, nrect, - rects); - } - } - - if (ret != 1) { - n = nrect; - r = rects; - while (n--) { - ExaCheckComposite (op, pSrc, pMask, pDst, - r->xSrc, r->ySrc, - r->xMask, r->yMask, - r->xDst, r->yDst, - r->width, r->height); - r++; - } - } + if (ret == -1 && op == PictOpOver && pMask && pMask->componentAlpha && + (!pExaScr->info->CheckComposite || + ((*pExaScr->info->CheckComposite) (PictOpOutReverse, pSrc, pMask, + pDst) && + (*pExaScr->info->CheckComposite) (PictOpAdd, pSrc, pMask, + pDst)))) { + ret = + exaTryDriverCompositeRects(PictOpOutReverse, pSrc, pMask, pDst, + nrect, rects); + if (ret == 1) { + op = PictOpAdd; + ret = exaTryDriverCompositeRects(op, pSrc, pMask, pDst, nrect, + rects); + } + } + + if (ret != 1) { + n = nrect; + r = rects; + while (n--) { + ExaCheckComposite(op, pSrc, pMask, pDst, + r->xSrc, r->ySrc, + r->xMask, r->yMask, + r->xDst, r->yDst, r->width, r->height); + r++; + } + } } - + /************************************************************/ if (!pMask) { - /* Now we have to flush the damage out from pendingDamage => damage - * Calling DamageRegionProcessPending has that effect. - */ + /* Now we have to flush the damage out from pendingDamage => damage + * Calling DamageRegionProcessPending has that effect. + */ - DamageRegionProcessPending(pDst->pDrawable); + DamageRegionProcessPending(pDst->pDrawable); } } static int -exaTryDriverComposite(CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height) +exaTryDriverComposite(CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { - ExaScreenPriv (pDst->pDrawable->pScreen); + ExaScreenPriv(pDst->pDrawable->pScreen); RegionRec region; BoxPtr pbox; int nbox; @@ -654,15 +641,15 @@ exaTryDriverComposite(CARD8 op, ExaPixmapPrivPtr pSrcExaPix = NULL, pMaskExaPix = NULL, pDstExaPix; if (pSrc->pDrawable) { - pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); - pSrcExaPix = ExaGetPixmapPriv(pSrcPix); + pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); + pSrcExaPix = ExaGetPixmapPriv(pSrcPix); } pDstPix = exaGetDrawablePixmap(pDst->pDrawable); pDstExaPix = ExaGetPixmapPriv(pDstPix); if (pMask && pMask->pDrawable) { - pMaskPix = exaGetDrawablePixmap(pMask->pDrawable); + pMaskPix = exaGetDrawablePixmap(pMask->pDrawable); pMaskExaPix = ExaGetPixmapPriv(pMaskPix); } @@ -671,96 +658,94 @@ exaTryDriverComposite(CARD8 op, * happens within limits. */ if (pDstExaPix->accel_blocked || - (pSrcExaPix && pSrcExaPix->accel_blocked) || - (pMaskExaPix && (pMaskExaPix->accel_blocked))) - { - return -1; + (pSrcExaPix && pSrcExaPix->accel_blocked) || + (pMaskExaPix && (pMaskExaPix->accel_blocked))) { + return -1; } xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; if (pMaskPix) { - xMask += pMask->pDrawable->x; - yMask += pMask->pDrawable->y; + xMask += pMask->pDrawable->x; + yMask += pMask->pDrawable->y; } if (pSrcPix) { - xSrc += pSrc->pDrawable->x; - ySrc += pSrc->pDrawable->y; + xSrc += pSrc->pDrawable->x; + ySrc += pSrc->pDrawable->y; } if (pExaScr->info->CheckComposite && - !(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst)) - { - return -1; + !(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst)) { + return -1; } - if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, - xSrc, ySrc, xMask, yMask, xDst, yDst, - width, height)) - return 1; + if (!miComputeCompositeRegion(®ion, pSrc, pMask, pDst, + xSrc, ySrc, xMask, yMask, xDst, yDst, + width, height)) + return 1; - exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y); + exaGetDrawableDeltas(pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y); RegionTranslate(®ion, dst_off_x, dst_off_y); if (pExaScr->do_migration) { - ExaMigrationRec pixmaps[3]; - int i = 0; - - pixmaps[i].as_dst = TRUE; - pixmaps[i].as_src = exaOpReadsDestination(op); - pixmaps[i].pPix = pDstPix; - pixmaps[i].pReg = pixmaps[0].as_src ? NULL : ®ion; - i++; - - if (pSrcPix) { - pixmaps[i].as_dst = FALSE; - pixmaps[i].as_src = TRUE; - pixmaps[i].pPix = pSrcPix; - pixmaps[i].pReg = NULL; - i++; - } - - if (pMaskPix) { - pixmaps[i].as_dst = FALSE; - pixmaps[i].as_src = TRUE; - pixmaps[i].pPix = pMaskPix; - pixmaps[i].pReg = NULL; - i++; - } - - exaDoMigration(pixmaps, i, TRUE); + ExaMigrationRec pixmaps[3]; + int i = 0; + + pixmaps[i].as_dst = TRUE; + pixmaps[i].as_src = exaOpReadsDestination(op); + pixmaps[i].pPix = pDstPix; + pixmaps[i].pReg = pixmaps[0].as_src ? NULL : ®ion; + i++; + + if (pSrcPix) { + pixmaps[i].as_dst = FALSE; + pixmaps[i].as_src = TRUE; + pixmaps[i].pPix = pSrcPix; + pixmaps[i].pReg = NULL; + i++; + } + + if (pMaskPix) { + pixmaps[i].as_dst = FALSE; + pixmaps[i].as_src = TRUE; + pixmaps[i].pPix = pMaskPix; + pixmaps[i].pReg = NULL; + i++; + } + + exaDoMigration(pixmaps, i, TRUE); } if (pSrcPix) { - pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y); - if (!pSrcPix) { - RegionUninit(®ion); - return 0; - } + pSrcPix = + exaGetOffscreenPixmap(pSrc->pDrawable, &src_off_x, &src_off_y); + if (!pSrcPix) { + RegionUninit(®ion); + return 0; + } } if (pMaskPix) { - pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x, - &mask_off_y); - if (!pMaskPix) { - RegionUninit(®ion); - return 0; - } + pMaskPix = exaGetOffscreenPixmap(pMask->pDrawable, &mask_off_x, + &mask_off_y); + if (!pMaskPix) { + RegionUninit(®ion); + return 0; + } } if (!exaPixmapHasGpuCopy(pDstPix)) { - RegionUninit(®ion); - return 0; + RegionUninit(®ion); + return 0; } if (!(*pExaScr->info->PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix, - pMaskPix, pDstPix)) - { - RegionUninit(®ion); - return -1; + pMaskPix, pDstPix)) { + RegionUninit(®ion); + return -1; } nbox = RegionNumRects(®ion); @@ -772,18 +757,16 @@ exaTryDriverComposite(CARD8 op, xSrc = xSrc + src_off_x - xDst - dst_off_x; ySrc = ySrc + src_off_y - yDst - dst_off_y; - while (nbox--) - { - (*pExaScr->info->Composite) (pDstPix, - pbox->x1 + xSrc, - pbox->y1 + ySrc, - pbox->x1 + xMask, - pbox->y1 + yMask, - pbox->x1, - pbox->y1, - pbox->x2 - pbox->x1, - pbox->y2 - pbox->y1); - pbox++; + while (nbox--) { + (*pExaScr->info->Composite) (pDstPix, + pbox->x1 + xSrc, + pbox->y1 + ySrc, + pbox->x1 + xMask, + pbox->y1 + yMask, + pbox->x1, + pbox->y1, + pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); + pbox++; } (*pExaScr->info->DoneComposite) (pDstPix); exaMarkSync(pDst->pDrawable->pScreen); @@ -843,28 +826,25 @@ exaTryDriverComposite(CARD8 op, static int exaTryMagicTwoPassCompositeHelper(CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height) + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, CARD16 width, CARD16 height) { - ExaScreenPriv (pDst->pDrawable->pScreen); + ExaScreenPriv(pDst->pDrawable->pScreen); assert(op == PictOpOver); if (pExaScr->info->CheckComposite && - (!(*pExaScr->info->CheckComposite)(PictOpOutReverse, pSrc, pMask, - pDst) || - !(*pExaScr->info->CheckComposite)(PictOpAdd, pSrc, pMask, pDst))) - { - return -1; + (!(*pExaScr->info->CheckComposite) (PictOpOutReverse, pSrc, pMask, + pDst) || + !(*pExaScr->info->CheckComposite) (PictOpAdd, pSrc, pMask, pDst))) { + return -1; } /* Now, we think we should be able to accelerate this operation. First, @@ -872,204 +852,197 @@ exaTryMagicTwoPassCompositeHelper(CARD8 op, * factors. */ exaComposite(PictOpOutReverse, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, - xDst, yDst, width, height); + xDst, yDst, width, height); /* Then, add in the source value times the destination alpha factors (1.0). */ exaComposite(PictOpAdd, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, - xDst, yDst, width, height); + xDst, yDst, width, height); return 1; } void -exaComposite(CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height) +exaComposite(CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { - ExaScreenPriv (pDst->pDrawable->pScreen); + ExaScreenPriv(pDst->pDrawable->pScreen); int ret = -1; Bool saveSrcRepeat = pSrc->repeat; Bool saveMaskRepeat = pMask ? pMask->repeat : 0; RegionRec region; if (pExaScr->swappedOut) - goto fallback; + goto fallback; /* Remove repeat in source if useless */ if (pSrc->pDrawable && pSrc->repeat && !pSrc->transform && xSrc >= 0 && - (xSrc + width) <= pSrc->pDrawable->width && ySrc >= 0 && - (ySrc + height) <= pSrc->pDrawable->height) - pSrc->repeat = 0; + (xSrc + width) <= pSrc->pDrawable->width && ySrc >= 0 && + (ySrc + height) <= pSrc->pDrawable->height) + pSrc->repeat = 0; if (!pMask && !pSrc->alphaMap && !pDst->alphaMap && - (op == PictOpSrc || (op == PictOpOver && !PICT_FORMAT_A(pSrc->format)))) + (op == PictOpSrc || (op == PictOpOver && !PICT_FORMAT_A(pSrc->format)))) { - if (pSrc->pDrawable ? - (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 && - pSrc->repeat) : - (pSrc->pSourcePict->type == SourcePictTypeSolidFill)) - { - ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst, - width, height); - if (ret == 1) - goto done; - } else if (pSrc->pDrawable && !pSrc->transform && - ((op == PictOpSrc && - (pSrc->format == pDst->format || - (PICT_FORMAT_COLOR(pDst->format) && - PICT_FORMAT_COLOR(pSrc->format) && - pDst->format == PICT_FORMAT(PICT_FORMAT_BPP(pSrc->format), - PICT_FORMAT_TYPE(pSrc->format), - 0, - PICT_FORMAT_R(pSrc->format), - PICT_FORMAT_G(pSrc->format), - PICT_FORMAT_B(pSrc->format))))) || - (op == PictOpOver && pSrc->format == pDst->format && - !PICT_FORMAT_A(pSrc->format)))) - { - if (!pSrc->repeat && xSrc >= 0 && ySrc >= 0 && - (xSrc + width <= pSrc->pDrawable->width) && - (ySrc + height <= pSrc->pDrawable->height)) - { - Bool ret; - xDst += pDst->pDrawable->x; - yDst += pDst->pDrawable->y; - xSrc += pSrc->pDrawable->x; - ySrc += pSrc->pDrawable->y; - - if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, - xSrc, ySrc, xMask, yMask, xDst, - yDst, width, height)) - goto done; - - ret = exaHWCopyNtoN(pSrc->pDrawable, pDst->pDrawable, NULL, - RegionRects(®ion), RegionNumRects(®ion), - xSrc - xDst, ySrc - yDst, FALSE, FALSE); - RegionUninit(®ion); - - /* Reset values to their original values. */ - xDst -= pDst->pDrawable->x; - yDst -= pDst->pDrawable->y; - xSrc -= pSrc->pDrawable->x; - ySrc -= pSrc->pDrawable->y; - - if (!ret) - goto fallback; - - goto done; - } - - if (pSrc->repeat && pSrc->repeatType == RepeatNormal && - pSrc->pDrawable->type == DRAWABLE_PIXMAP) - { - DDXPointRec patOrg; - - /* Let's see if the driver can do the repeat in one go */ - if (pExaScr->info->PrepareComposite && !pSrc->alphaMap && - !pDst->alphaMap) - { - ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, - ySrc, xMask, yMask, xDst, yDst, - width, height); - if (ret == 1) - goto done; - } - - /* Now see if we can use exaFillRegionTiled() */ - xDst += pDst->pDrawable->x; - yDst += pDst->pDrawable->y; - xSrc += pSrc->pDrawable->x; - ySrc += pSrc->pDrawable->y; - - if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, xSrc, - ySrc, xMask, yMask, xDst, yDst, - width, height)) - goto done; - - /* pattern origin is the point in the destination drawable - * corresponding to (0,0) in the source */ - patOrg.x = xDst - xSrc; - patOrg.y = yDst - ySrc; - - ret = exaFillRegionTiled(pDst->pDrawable, ®ion, - (PixmapPtr)pSrc->pDrawable, - &patOrg, FB_ALLONES, GXcopy, CT_NONE); - - RegionUninit(®ion); - - if (ret) - goto done; - - /* Let's be correct and restore the variables to their original state. */ - xDst -= pDst->pDrawable->x; - yDst -= pDst->pDrawable->y; - xSrc -= pSrc->pDrawable->x; - ySrc -= pSrc->pDrawable->y; - } - } + if (pSrc->pDrawable ? + (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 && + pSrc->repeat) : + (pSrc->pSourcePict->type == SourcePictTypeSolidFill)) { + ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst, + width, height); + if (ret == 1) + goto done; + } + else if (pSrc->pDrawable && !pSrc->transform && + ((op == PictOpSrc && + (pSrc->format == pDst->format || + (PICT_FORMAT_COLOR(pDst->format) && + PICT_FORMAT_COLOR(pSrc->format) && + pDst->format == PICT_FORMAT(PICT_FORMAT_BPP(pSrc->format), + PICT_FORMAT_TYPE(pSrc->format), + 0, + PICT_FORMAT_R(pSrc->format), + PICT_FORMAT_G(pSrc->format), + PICT_FORMAT_B(pSrc->format))))) + || (op == PictOpOver && pSrc->format == pDst->format && + !PICT_FORMAT_A(pSrc->format)))) { + if (!pSrc->repeat && xSrc >= 0 && ySrc >= 0 && + (xSrc + width <= pSrc->pDrawable->width) && + (ySrc + height <= pSrc->pDrawable->height)) { + Bool ret; + + xDst += pDst->pDrawable->x; + yDst += pDst->pDrawable->y; + xSrc += pSrc->pDrawable->x; + ySrc += pSrc->pDrawable->y; + + if (!miComputeCompositeRegion(®ion, pSrc, pMask, pDst, + xSrc, ySrc, xMask, yMask, xDst, + yDst, width, height)) + goto done; + + ret = exaHWCopyNtoN(pSrc->pDrawable, pDst->pDrawable, NULL, + RegionRects(®ion), + RegionNumRects(®ion), xSrc - xDst, + ySrc - yDst, FALSE, FALSE); + RegionUninit(®ion); + + /* Reset values to their original values. */ + xDst -= pDst->pDrawable->x; + yDst -= pDst->pDrawable->y; + xSrc -= pSrc->pDrawable->x; + ySrc -= pSrc->pDrawable->y; + + if (!ret) + goto fallback; + + goto done; + } + + if (pSrc->repeat && pSrc->repeatType == RepeatNormal && + pSrc->pDrawable->type == DRAWABLE_PIXMAP) { + DDXPointRec patOrg; + + /* Let's see if the driver can do the repeat in one go */ + if (pExaScr->info->PrepareComposite && !pSrc->alphaMap && + !pDst->alphaMap) { + ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, + ySrc, xMask, yMask, xDst, yDst, + width, height); + if (ret == 1) + goto done; + } + + /* Now see if we can use exaFillRegionTiled() */ + xDst += pDst->pDrawable->x; + yDst += pDst->pDrawable->y; + xSrc += pSrc->pDrawable->x; + ySrc += pSrc->pDrawable->y; + + if (!miComputeCompositeRegion(®ion, pSrc, pMask, pDst, xSrc, + ySrc, xMask, yMask, xDst, yDst, + width, height)) + goto done; + + /* pattern origin is the point in the destination drawable + * corresponding to (0,0) in the source */ + patOrg.x = xDst - xSrc; + patOrg.y = yDst - ySrc; + + ret = exaFillRegionTiled(pDst->pDrawable, ®ion, + (PixmapPtr) pSrc->pDrawable, + &patOrg, FB_ALLONES, GXcopy, CT_NONE); + + RegionUninit(®ion); + + if (ret) + goto done; + + /* Let's be correct and restore the variables to their original state. */ + xDst -= pDst->pDrawable->x; + yDst -= pDst->pDrawable->y; + xSrc -= pSrc->pDrawable->x; + ySrc -= pSrc->pDrawable->y; + } + } } /* Remove repeat in mask if useless */ if (pMask && pMask->pDrawable && pMask->repeat && !pMask->transform && - xMask >= 0 && (xMask + width) <= pMask->pDrawable->width && - yMask >= 0 && (yMask + height) <= pMask->pDrawable->height) - pMask->repeat = 0; + xMask >= 0 && (xMask + width) <= pMask->pDrawable->width && + yMask >= 0 && (yMask + height) <= pMask->pDrawable->height) + pMask->repeat = 0; if (pExaScr->info->PrepareComposite && - !pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap) - { - Bool isSrcSolid; - - ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, - yMask, xDst, yDst, width, height); - if (ret == 1) - goto done; - - /* For generic masks and solid src pictures, mach64 can do Over in two - * passes, similar to the component-alpha case. - */ - isSrcSolid = pSrc->pDrawable ? - (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 && - pSrc->repeat) : - (pSrc->pSourcePict->type == SourcePictTypeSolidFill); - - /* If we couldn't do the Composite in a single pass, and it was a - * component-alpha Over, see if we can do it in two passes with - * an OutReverse and then an Add. - */ - if (ret == -1 && op == PictOpOver && pMask && - (pMask->componentAlpha || isSrcSolid)) { - ret = exaTryMagicTwoPassCompositeHelper(op, pSrc, pMask, pDst, - xSrc, ySrc, - xMask, yMask, xDst, yDst, - width, height); - if (ret == 1) - goto done; - } + !pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap) { + Bool isSrcSolid; + + ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, + yMask, xDst, yDst, width, height); + if (ret == 1) + goto done; + + /* For generic masks and solid src pictures, mach64 can do Over in two + * passes, similar to the component-alpha case. + */ + isSrcSolid = pSrc->pDrawable ? + (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 && + pSrc->repeat) : + (pSrc->pSourcePict->type == SourcePictTypeSolidFill); + + /* If we couldn't do the Composite in a single pass, and it was a + * component-alpha Over, see if we can do it in two passes with + * an OutReverse and then an Add. + */ + if (ret == -1 && op == PictOpOver && pMask && + (pMask->componentAlpha || isSrcSolid)) { + ret = exaTryMagicTwoPassCompositeHelper(op, pSrc, pMask, pDst, + xSrc, ySrc, + xMask, yMask, xDst, yDst, + width, height); + if (ret == 1) + goto done; + } } -fallback: + fallback: #if DEBUG_TRACE_FALL - exaPrintCompositeFallback (op, pSrc, pMask, pDst); + exaPrintCompositeFallback(op, pSrc, pMask, pDst); #endif - ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc, - xMask, yMask, xDst, yDst, width, height); + ExaCheckComposite(op, pSrc, pMask, pDst, xSrc, ySrc, + xMask, yMask, xDst, yDst, width, height); -done: + done: pSrc->repeat = saveSrcRepeat; if (pMask) - pMask->repeat = saveMaskRepeat; + pMask->repeat = saveMaskRepeat; } /** @@ -1080,51 +1053,47 @@ done: * See the comments about exaTrapezoids and exaTriangles. */ static PicturePtr -exaCreateAlphaPicture (ScreenPtr pScreen, - PicturePtr pDst, - PictFormatPtr pPictFormat, - CARD16 width, - CARD16 height) +exaCreateAlphaPicture(ScreenPtr pScreen, + PicturePtr pDst, + PictFormatPtr pPictFormat, CARD16 width, CARD16 height) { - PixmapPtr pPixmap; - PicturePtr pPicture; - GCPtr pGC; - int error; - xRectangle rect; + PixmapPtr pPixmap; + PicturePtr pPicture; + GCPtr pGC; + int error; + xRectangle rect; if (width > 32767 || height > 32767) - return 0; - - if (!pPictFormat) - { - if (pDst->polyEdge == PolyEdgeSharp) - pPictFormat = PictureMatchFormat (pScreen, 1, PICT_a1); - else - pPictFormat = PictureMatchFormat (pScreen, 8, PICT_a8); - if (!pPictFormat) - return 0; + return 0; + + if (!pPictFormat) { + if (pDst->polyEdge == PolyEdgeSharp) + pPictFormat = PictureMatchFormat(pScreen, 1, PICT_a1); + else + pPictFormat = PictureMatchFormat(pScreen, 8, PICT_a8); + if (!pPictFormat) + return 0; } pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, - pPictFormat->depth, 0); + pPictFormat->depth, 0); if (!pPixmap) - return 0; - pGC = GetScratchGC (pPixmap->drawable.depth, pScreen); - if (!pGC) - { - (*pScreen->DestroyPixmap) (pPixmap); - return 0; + return 0; + pGC = GetScratchGC(pPixmap->drawable.depth, pScreen); + if (!pGC) { + (*pScreen->DestroyPixmap) (pPixmap); + return 0; } - ValidateGC (&pPixmap->drawable, pGC); + ValidateGC(&pPixmap->drawable, pGC); rect.x = 0; rect.y = 0; rect.width = width; rect.height = height; - ExaCheckPolyFillRect (&pPixmap->drawable, pGC, 1, &rect); - exaPixmapDirty (pPixmap, 0, 0, width, height); - FreeScratchGC (pGC); - pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat, - 0, 0, serverClient, &error); + ExaCheckPolyFillRect(&pPixmap->drawable, pGC, 1, &rect); + exaPixmapDirty(pPixmap, 0, 0, width, height); + FreeScratchGC(pGC); + pPicture = CreatePicture(0, &pPixmap->drawable, pPictFormat, + 0, 0, serverClient, &error); (*pScreen->DestroyPixmap) (pPixmap); return pPicture; } @@ -1143,53 +1112,52 @@ exaCreateAlphaPicture (ScreenPtr pScreen, * to initialize the contents. */ void -exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst, - PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, - int ntrap, xTrapezoid *traps) +exaTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, + PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, + int ntrap, xTrapezoid * traps) { - ScreenPtr pScreen = pDst->pDrawable->pScreen; - PictureScreenPtr ps = GetPictureScreen(pScreen); - BoxRec bounds; + ScreenPtr pScreen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + BoxRec bounds; if (maskFormat) { - PicturePtr pPicture; - INT16 xDst, yDst; - INT16 xRel, yRel; - - miTrapezoidBounds (ntrap, traps, &bounds); - - if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) - return; - - xDst = traps[0].left.p1.x >> 16; - yDst = traps[0].left.p1.y >> 16; - - pPicture = exaCreateAlphaPicture (pScreen, pDst, maskFormat, - bounds.x2 - bounds.x1, - bounds.y2 - bounds.y1); - if (!pPicture) - return; - - exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST); - for (; ntrap; ntrap--, traps++) - (*ps->RasterizeTrapezoid) (pPicture, traps, - -bounds.x1, -bounds.y1); - exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST); - - 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); - } else { - if (pDst->polyEdge == PolyEdgeSharp) - maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1); - else - maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8); - for (; ntrap; ntrap--, traps++) - exaTrapezoids (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps); + PicturePtr pPicture; + INT16 xDst, yDst; + INT16 xRel, yRel; + + miTrapezoidBounds(ntrap, traps, &bounds); + + if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) + return; + + xDst = traps[0].left.p1.x >> 16; + yDst = traps[0].left.p1.y >> 16; + + pPicture = exaCreateAlphaPicture(pScreen, pDst, maskFormat, + bounds.x2 - bounds.x1, + bounds.y2 - bounds.y1); + if (!pPicture) + return; + + exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST); + for (; ntrap; ntrap--, traps++) + (*ps->RasterizeTrapezoid) (pPicture, traps, -bounds.x1, -bounds.y1); + exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST); + + 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); + } + else { + if (pDst->polyEdge == PolyEdgeSharp) + maskFormat = PictureMatchFormat(pScreen, 1, PICT_a1); + else + maskFormat = PictureMatchFormat(pScreen, 8, PICT_a8); + for (; ntrap; ntrap--, traps++) + exaTrapezoids(op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps); } } @@ -1207,50 +1175,51 @@ exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst, * to initialize the contents. */ void -exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst, - PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, - int ntri, xTriangle *tris) +exaTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst, + PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, + int ntri, xTriangle * tris) { - ScreenPtr pScreen = pDst->pDrawable->pScreen; - PictureScreenPtr ps = GetPictureScreen(pScreen); - BoxRec bounds; + ScreenPtr pScreen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + BoxRec bounds; if (maskFormat) { - PicturePtr pPicture; - INT16 xDst, yDst; - INT16 xRel, yRel; - - miTriangleBounds (ntri, tris, &bounds); - - if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) - return; - - xDst = tris[0].p1.x >> 16; - yDst = tris[0].p1.y >> 16; - - pPicture = exaCreateAlphaPicture (pScreen, pDst, maskFormat, - bounds.x2 - bounds.x1, - bounds.y2 - bounds.y1); - if (!pPicture) - return; - - exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST); - (*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris); - exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST); - - 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); - } else { - if (pDst->polyEdge == PolyEdgeSharp) - maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1); - else - maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8); - - for (; ntri; ntri--, tris++) - exaTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris); + PicturePtr pPicture; + INT16 xDst, yDst; + INT16 xRel, yRel; + + miTriangleBounds(ntri, tris, &bounds); + + if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) + return; + + xDst = tris[0].p1.x >> 16; + yDst = tris[0].p1.y >> 16; + + pPicture = exaCreateAlphaPicture(pScreen, pDst, maskFormat, + bounds.x2 - bounds.x1, + bounds.y2 - bounds.y1); + if (!pPicture) + return; + + exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST); + (*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris); + exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST); + + 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); + } + else { + if (pDst->polyEdge == PolyEdgeSharp) + maskFormat = PictureMatchFormat(pScreen, 1, PICT_a1); + else + maskFormat = PictureMatchFormat(pScreen, 8, PICT_a8); + + for (; ntri; ntri--, tris++) + exaTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris); } } |