diff options
Diffstat (limited to 'xorg-server/exa/exa_render.c')
-rw-r--r-- | xorg-server/exa/exa_render.c | 276 |
1 files changed, 171 insertions, 105 deletions
diff --git a/xorg-server/exa/exa_render.c b/xorg-server/exa/exa_render.c index 9a79b4781..1ac29f233 100644 --- a/xorg-server/exa/exa_render.c +++ b/xorg-server/exa/exa_render.c @@ -54,6 +54,12 @@ static void exaCompositeFallbackPictDesc(PicturePtr pict, char *string, int n) case PICT_x8r8g8b8: snprintf(format, 20, "XRGB8888"); break; + case PICT_b8g8r8a8: + snprintf(format, 20, "BGRA8888"); + break; + case PICT_b8g8r8x8: + snprintf(format, 20, "BGRX8888"); + break; case PICT_r5g6b5: snprintf(format, 20, "RGB565 "); break; @@ -158,12 +164,18 @@ exaGetPixelFromRGBA(CARD32 *pixel, gshift = bbits; rshift = gshift + gbits; ashift = rshift + rbits; - } else { /* PICT_TYPE_ABGR */ + } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) { rshift = 0; gshift = rbits; bshift = gshift + gbits; ashift = bshift + bbits; - } + } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) { + bshift = PICT_FORMAT_BPP(format) - bbits; + gshift = bshift - gbits; + rshift = gshift - rbits; + ashift = 0; + } else + return FALSE; *pixel |= ( blue >> (16 - bbits)) << bshift; *pixel |= ( red >> (16 - rbits)) << rshift; @@ -197,12 +209,18 @@ exaGetRGBAFromPixel(CARD32 pixel, gshift = bbits; rshift = gshift + gbits; ashift = rshift + rbits; - } else { /* PICT_TYPE_ABGR */ + } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) { rshift = 0; gshift = rbits; bshift = gshift + gbits; ashift = bshift + bbits; - } + } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) { + bshift = PICT_FORMAT_BPP(format) - bbits; + gshift = bshift - gbits; + rshift = gshift - rbits; + ashift = 0; + } else + return FALSE; *red = ((pixel >> rshift ) & ((1 << rbits) - 1)) << (16 - rbits); while (rbits < 16) { @@ -253,7 +271,6 @@ exaTryDriverSolidFill(PicturePtr pSrc, ExaPixmapPrivPtr pSrcExaPix, pDstExaPix; CARD32 pixel; CARD16 red, green, blue, alpha; - ExaMigrationRec pixmaps[1]; pDstPix = exaGetDrawablePixmap (pDst->pDrawable); pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable); @@ -284,11 +301,15 @@ exaTryDriverSolidFill(PicturePtr pSrc, pixel = exaGetPixmapFirstPixel (pSrcPix); - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = FALSE; - pixmaps[0].pPix = pDstPix; - pixmaps[0].pReg = ®ion; - exaDoMigration(pixmaps, 1, TRUE); + if (pExaScr->do_migration) { + 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); + } if (!exaPixmapIsOffscreen(pDstPix)) { REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); @@ -334,16 +355,15 @@ exaTryDriverSolidFill(PicturePtr pSrc, static int exaTryDriverCompositeRects(CARD8 op, PicturePtr pSrc, + PicturePtr pMask, PicturePtr pDst, int nrect, ExaCompositeRectPtr rects) { ExaScreenPriv (pDst->pDrawable->pScreen); - int src_off_x, src_off_y, dst_off_x, dst_off_y; - PixmapPtr pSrcPix, pDstPix; - ExaPixmapPrivPtr pSrcExaPix, pDstExaPix; - struct _Pixmap scratch; - ExaMigrationRec pixmaps[2]; + int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y; + PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix; + ExaPixmapPrivPtr pSrcExaPix, pMaskExaPix = NULL, pDstExaPix; if (!pExaScr->info->PrepareComposite) return -1; @@ -351,6 +371,11 @@ exaTryDriverCompositeRects(CARD8 op, pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); pSrcExaPix = ExaGetPixmapPriv(pSrcPix); + if (pMask) { + pMaskPix = exaGetDrawablePixmap(pMask->pDrawable); + pMaskExaPix = ExaGetPixmapPriv(pMaskPix); + } + pDstPix = exaGetDrawablePixmap(pDst->pDrawable); pDstExaPix = ExaGetPixmapPriv(pDstPix); @@ -358,61 +383,74 @@ exaTryDriverCompositeRects(CARD8 op, * FIXME: If it cannot, use temporary pixmaps so that the drawing * happens within limits. */ - if (pSrcExaPix->accel_blocked || - pDstExaPix->accel_blocked) + if (pSrcExaPix->accel_blocked || pDstExaPix->accel_blocked || + (pMask && pMaskExaPix->accel_blocked)) { return -1; } if (pExaScr->info->CheckComposite && - !(*pExaScr->info->CheckComposite) (op, pSrc, NULL, pDst)) + !(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst)) { return -1; } - - exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y); - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = exaOpReadsDestination(op); - pixmaps[0].pPix = pDstPix; - pixmaps[0].pReg = NULL; - pixmaps[1].as_dst = FALSE; - pixmaps[1].as_src = TRUE; - pixmaps[1].pPix = pSrcPix; - pixmaps[1].pReg = NULL; - exaDoMigration(pixmaps, 2, TRUE); + if (pExaScr->do_migration) { + ExaMigrationRec pixmaps[3]; + + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = exaOpReadsDestination(op); + pixmaps[0].pPix = pDstPix; + pixmaps[0].pReg = NULL; + pixmaps[1].as_dst = FALSE; + pixmaps[1].as_src = TRUE; + pixmaps[1].pPix = pSrcPix; + pixmaps[1].pReg = NULL; + if (pMask) { + pixmaps[2].as_dst = FALSE; + pixmaps[2].as_src = TRUE; + pixmaps[2].pPix = pMaskPix; + pixmaps[2].pReg = NULL; + exaDoMigration(pixmaps, 3, TRUE); + } else + exaDoMigration(pixmaps, 2, TRUE); + } - pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y); - if (!exaPixmapIsOffscreen(pDstPix)) + pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y); + if (!pDstPix) return 0; - if (!pSrcPix && pExaScr->info->UploadToScratch) - { - pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable); - if ((*pExaScr->info->UploadToScratch) (pSrcPix, &scratch)) - pSrcPix = &scratch; - } + pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y); if (!pSrcPix) return 0; - if (!(*pExaScr->info->PrepareComposite) (op, pSrc, NULL, pDst, pSrcPix, - NULL, pDstPix)) + if (pMask) { + 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 = pMask ? rects->xMask + pMask->pDrawable->x : 0; + INT16 yMask = pMask ? rects->yMask + pMask->pDrawable->y : 0; INT16 xSrc = rects->xSrc + pSrc->pDrawable->x; INT16 ySrc = rects->ySrc + pSrc->pDrawable->y; RegionRec region; BoxPtr pbox; int nbox; - - if (!miComputeCompositeRegion (®ion, pSrc, NULL, pDst, - xSrc, ySrc, 0, 0, xDst, yDst, + + if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, + xSrc, ySrc, xMask, yMask, xDst, yDst, rects->width, rects->height)) goto next_rect; @@ -421,6 +459,8 @@ exaTryDriverCompositeRects(CARD8 op, nbox = REGION_NUM_RECTS(®ion); pbox = REGION_RECTS(®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; @@ -429,7 +469,8 @@ exaTryDriverCompositeRects(CARD8 op, (*pExaScr->info->Composite) (pDstPix, pbox->x1 + xSrc, pbox->y1 + ySrc, - 0, 0, + pbox->x1 + xMask, + pbox->y1 + yMask, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, @@ -451,25 +492,28 @@ exaTryDriverCompositeRects(CARD8 op, /** * Copy a number of rectangles from source to destination in a single - * operation. This is specialized for building a glyph mask: we don'y - * have a mask argument because we don't need it for that, and we - * don't have he special-case fallbacks found in exaComposite() - if the - * driver can support it, we use the driver functionality, otherwise we - * fallback straight to software. + * operation. This is specialized for glyph rendering: we don't have the + * special-case fallbacks found in exaComposite() - if the driver can support + * it, we use the driver functionality, otherwise we fall back straight to + * software. */ void exaCompositeRects(CARD8 op, PicturePtr pSrc, + PicturePtr pMask, PicturePtr pDst, int nrect, ExaCompositeRectPtr rects) { - PixmapPtr pPixmap = exaGetDrawablePixmap(pDst->pDrawable); - ExaPixmapPriv(pPixmap); + ExaScreenPriv (pDst->pDrawable->pScreen); int n; ExaCompositeRectPtr r; - - if (pExaPixmap->pDamage) { + int ret; + + /* If we get a mask, that means we're rendering to the exaGlyphs + * destination directly, so the damage layer takes care of this. + */ + if (!pMask) { RegionRec region; int x1 = MAXSHORT; int y1 = MAXSHORT; @@ -526,24 +570,44 @@ exaCompositeRects(CARD8 op, /************************************************************/ ValidatePicture (pSrc); + if (pMask) + ValidatePicture (pMask); ValidatePicture (pDst); - - if (exaTryDriverCompositeRects(op, pSrc, pDst, nrect, rects) != 1) { - n = nrect; - r = rects; - while (n--) { - ExaCheckComposite (op, pSrc, NULL, pDst, - r->xSrc, r->ySrc, - 0, 0, - r->xDst, r->yDst, - r->width, r->height); - r++; + + 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 (pExaPixmap->pDamage) { + if (!pMask) { /* Now we have to flush the damage out from pendingDamage => damage * Calling DamageRegionProcessPending has that effect. */ @@ -573,8 +637,6 @@ exaTryDriverComposite(CARD8 op, int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y; PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix; ExaPixmapPrivPtr pSrcExaPix, pMaskExaPix = NULL, pDstExaPix; - struct _Pixmap scratch; - ExaMigrationRec pixmaps[3]; pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); pSrcExaPix = ExaGetPixmapPriv(pSrcPix); @@ -624,22 +686,25 @@ exaTryDriverComposite(CARD8 op, REGION_TRANSLATE(pScreen, ®ion, dst_off_x, dst_off_y); - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = exaOpReadsDestination(op); - pixmaps[0].pPix = pDstPix; - pixmaps[0].pReg = pixmaps[0].as_src ? NULL : ®ion; - pixmaps[1].as_dst = FALSE; - pixmaps[1].as_src = TRUE; - pixmaps[1].pPix = pSrcPix; - pixmaps[1].pReg = NULL; - if (pMask) { - pixmaps[2].as_dst = FALSE; - pixmaps[2].as_src = TRUE; - pixmaps[2].pPix = pMaskPix; - pixmaps[2].pReg = NULL; - exaDoMigration(pixmaps, 3, TRUE); - } else { - exaDoMigration(pixmaps, 2, TRUE); + if (pExaScr->do_migration) { + ExaMigrationRec pixmaps[3]; + + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = exaOpReadsDestination(op); + pixmaps[0].pPix = pDstPix; + pixmaps[0].pReg = pixmaps[0].as_src ? NULL : ®ion; + pixmaps[1].as_dst = FALSE; + pixmaps[1].as_src = TRUE; + pixmaps[1].pPix = pSrcPix; + pixmaps[1].pReg = NULL; + if (pMask) { + pixmaps[2].as_dst = FALSE; + pixmaps[2].as_src = TRUE; + pixmaps[2].pPix = pMaskPix; + pixmaps[2].pReg = NULL; + exaDoMigration(pixmaps, 3, TRUE); + } else + exaDoMigration(pixmaps, 2, TRUE); } pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y); @@ -652,16 +717,6 @@ exaTryDriverComposite(CARD8 op, return 0; } - if (!pSrcPix && (!pMask || pMaskPix) && pExaScr->info->UploadToScratch) { - pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable); - if ((*pExaScr->info->UploadToScratch) (pSrcPix, &scratch)) - pSrcPix = &scratch; - } else if (pSrcPix && pMask && !pMaskPix && pExaScr->info->UploadToScratch) { - pMaskPix = exaGetDrawablePixmap (pMask->pDrawable); - if ((*pExaScr->info->UploadToScratch) (pMaskPix, &scratch)) - pMaskPix = &scratch; - } - if (!pSrcPix || (pMask && !pMaskPix)) { REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); return 0; @@ -832,11 +887,13 @@ exaComposite(CARD8 op, { if ((op == PictOpSrc && ((pSrc->format == pDst->format) || + (pSrc->format==PICT_b8g8r8a8 && pDst->format==PICT_b8g8r8x8) || (pSrc->format==PICT_a8r8g8b8 && pDst->format==PICT_x8r8g8b8) || (pSrc->format==PICT_a8b8g8r8 && pDst->format==PICT_x8b8g8r8))) || (op == PictOpOver && !pSrc->alphaMap && !pDst->alphaMap && pSrc->format == pDst->format && - (pSrc->format==PICT_x8r8g8b8 || pSrc->format==PICT_x8b8g8r8))) + (pSrc->format==PICT_x8r8g8b8 || pSrc->format==PICT_x8b8g8r8 || + pSrc->format==PICT_b8g8r8x8))) { if (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 && @@ -851,6 +908,7 @@ exaComposite(CARD8 op, !pSrc->repeat && !pSrc->transform) { + Bool ret; xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; xSrc += pSrc->pDrawable->x; @@ -861,12 +919,20 @@ exaComposite(CARD8 op, yDst, width, height)) goto done; - - exaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, NULL, + ret = exaHWCopyNtoN(pSrc->pDrawable, pDst->pDrawable, NULL, REGION_RECTS(®ion), REGION_NUM_RECTS(®ion), - xSrc - xDst, ySrc - yDst, - FALSE, FALSE, 0, NULL); + xSrc - xDst, ySrc - yDst, FALSE, FALSE); REGION_UNINIT(pDst->pDrawable->pScreen, ®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; } else if (pSrc->pDrawable != NULL && @@ -1054,15 +1120,15 @@ exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst, 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; - PicturePtr pPicture; - INT16 xDst, yDst; - INT16 xRel, yRel; - xDst = traps[0].left.p1.x >> 16; yDst = traps[0].left.p1.y >> 16; @@ -1118,15 +1184,15 @@ exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst, 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; - PicturePtr pPicture; - INT16 xDst, yDst; - INT16 xRel, yRel; - xDst = tris[0].p1.x >> 16; yDst = tris[0].p1.y >> 16; |