static Bool ExaPrepareCompositeReg(ScreenPtr pScreen, CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { RegionRec region; RegionPtr dstReg = NULL; RegionPtr srcReg = NULL; RegionPtr maskReg = NULL; PixmapPtr pSrcPix = NULL; PixmapPtr pMaskPix = NULL; PixmapPtr pDstPix; ExaScreenPriv(pScreen); Bool ret; RegionNull(®ion); if (pSrc->pDrawable) { pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); RegionNull(&pExaScr->srcReg); srcReg = &pExaScr->srcReg; pExaScr->srcPix = pSrcPix; if (pSrc != pDst) RegionTranslate(pSrc->pCompositeClip, -pSrc->pDrawable->x, -pSrc->pDrawable->y); } else pExaScr->srcPix = NULL; if (pMask && pMask->pDrawable) { pMaskPix = exaGetDrawablePixmap(pMask->pDrawable); RegionNull(&pExaScr->maskReg); maskReg = &pExaScr->maskReg; pExaScr->maskPix = pMaskPix; if (pMask != pDst && pMask != pSrc) RegionTranslate(pMask->pCompositeClip, -pMask->pDrawable->x, -pMask->pDrawable->y); } else pExaScr->maskPix = NULL; RegionTranslate(pDst->pCompositeClip, -pDst->pDrawable->x, -pDst->pDrawable->y); pExaScr->SavedSourceValidate = ExaSrcValidate; swap(pExaScr, pScreen, SourceValidate); ret = miComputeCompositeRegion(®ion, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); swap(pExaScr, pScreen, SourceValidate); RegionTranslate(pDst->pCompositeClip, pDst->pDrawable->x, pDst->pDrawable->y); if (pSrc->pDrawable && pSrc != pDst) RegionTranslate(pSrc->pCompositeClip, pSrc->pDrawable->x, pSrc->pDrawable->y); if (pMask && pMask->pDrawable && pMask != pDst && pMask != pSrc) RegionTranslate(pMask->pCompositeClip, pMask->pDrawable->x, pMask->pDrawable->y); if (!ret) { if (srcReg) RegionUninit(srcReg); if (maskReg) RegionUninit(maskReg); return FALSE; } /** * Don't limit alphamaps readbacks for now until we've figured out how that * should be done. */ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) pExaScr-> prepare_access_reg(exaGetDrawablePixmap(pSrc->alphaMap->pDrawable), EXA_PREPARE_AUX_SRC, NULL); if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) pExaScr-> prepare_access_reg(exaGetDrawablePixmap(pMask->alphaMap->pDrawable), EXA_PREPARE_AUX_MASK, NULL); if (pSrcPix) pExaScr->prepare_access_reg(pSrcPix, EXA_PREPARE_SRC, srcReg); if (pMaskPix) pExaScr->prepare_access_reg(pMaskPix, EXA_PREPARE_MASK, maskReg); if (srcReg) RegionUninit(srcReg); if (maskReg) RegionUninit(maskReg); pDstPix = exaGetDrawablePixmap(pDst->pDrawable); if (!exaOpReadsDestination(op)) { int xoff; int yoff; exaGetDrawableDeltas(pDst->pDrawable, pDstPix, &xoff, &yoff); RegionTranslate(®ion, pDst->pDrawable->x + xoff, pDst->pDrawable->y + yoff); dstReg = ®ion; } if (pDst->alphaMap && pDst->alphaMap->pDrawable) pExaScr-> prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable), EXA_PREPARE_AUX_DEST, dstReg); pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, dstReg); RegionUninit(®ion); return TRUE; }
void tridentComposite (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { SetupTrident (pDst->pDrawable->pScreen); tridentScreenInfo(pScreenPriv); RegionRec region; int n; BoxPtr pbox; CARD32 rgb; CARD8 *msk, *mskLine; FbBits *mskBits; FbStride mskStride; int mskBpp; int mskXoff, mskYoff; CARD32 *src, *srcLine; CARD32 *off, *offLine; FbBits *srcBits; FbStride srcStride; int srcXoff, srcYoff; FbStride offStride; int srcBpp; int x_msk, y_msk, x_src, y_src, x_dst, y_dst; int x2; int w, h, w_this, h_this, w_remain; CARD32 *off_screen; int off_size = tridents->off_screen_size >> 2; int off_width, off_height; int stride = pScreenPriv->screen->fb[0].pixelStride; int mskExtra; CARD32 off_screen_offset = tridents->off_screen - tridents->screen; int mode; #define MODE_NONE 0 #define MODE_IMAGE 1 #define MODE_MASK 2 rgb = *((CARD32 *) ((PixmapPtr) (pSrc->pDrawable))->devPrivate.ptr); if (pMask && !pMask->repeat && pMask->format == PICT_a8 && op == PictOpOver && pSrc->repeat && pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 && PICT_FORMAT_BPP(pSrc->format) == 32 && (PICT_FORMAT_A(pSrc->format) == 0 || (rgb & 0xff000000) == 0xff000000) && pDst->pDrawable->bitsPerPixel == 32 && pDst->pDrawable->type == DRAWABLE_WINDOW) { mode = MODE_MASK; } else if (!pMask && op == PictOpOver && !pSrc->repeat && PICT_FORMAT_A(pSrc->format) == 8 && PICT_FORMAT_BPP(pSrc->format) == 32 && pDst->pDrawable->bitsPerPixel == 32 && pDst->pDrawable->type == DRAWABLE_WINDOW) { mode = MODE_IMAGE; } else mode = MODE_NONE; if (mode != MODE_NONE) { xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; xSrc += pSrc->pDrawable->x; ySrc += pSrc->pDrawable->y; fbGetDrawable (pSrc->pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); if (pMask) { xMask += pMask->pDrawable->x; yMask += pMask->pDrawable->y; fbGetDrawable (pMask->pDrawable, mskBits, mskStride, mskBpp, mskXoff, mskYoff); mskStride = mskStride * sizeof (FbBits) / sizeof (CARD8); } if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) return; _tridentInit(cop,tridentc); cop->multi = COP_MULTI_PATTERN; cop->src_offset = off_screen_offset; if (mode == MODE_IMAGE) { cop->multi = (COP_MULTI_ALPHA | COP_ALPHA_BLEND_ENABLE | COP_ALPHA_WRITE_ENABLE | 0x7 << 16 | COP_ALPHA_DST_BLEND_1_SRC_A | COP_ALPHA_SRC_BLEND_1); } else { rgb &= 0xffffff; cop->multi = (COP_MULTI_ALPHA | COP_ALPHA_BLEND_ENABLE | COP_ALPHA_WRITE_ENABLE | 0x7 << 16 | COP_ALPHA_DST_BLEND_1_SRC_A | COP_ALPHA_SRC_BLEND_SRC_A); } n = REGION_NUM_RECTS (®ion); pbox = REGION_RECTS (®ion); while (n--) { h = pbox->y2 - pbox->y1; w = pbox->x2 - pbox->x1; offStride = (w + 7) & ~7; off_height = off_size / offStride; if (off_height > h) off_height = h; cop->multi = COP_MULTI_STRIDE | (stride << 16) | offStride; y_dst = pbox->y1; y_src = y_dst - yDst + ySrc; y_msk = y_dst - yDst + yMask; x_dst = pbox->x1; x_src = x_dst - xDst + xSrc; x_msk = x_dst - xDst + xMask; if (mode == MODE_IMAGE) srcLine = (CARD32 *) srcBits + (y_src - srcYoff) * srcStride + (x_src - srcXoff); else mskLine = (CARD8 *) mskBits + (y_msk - mskYoff) * mskStride + (x_msk - mskXoff); while (h) { h_this = h; if (h_this > off_height) h_this = off_height; h -= h_this; offLine = (CARD32 *) tridents->off_screen; _tridentWaitDone(cop); cop->dst_start_xy = TRI_XY(x_dst, y_dst); cop->dst_end_xy = TRI_XY(x_dst + w - 1, y_dst + h_this - 1); cop->src_start_xy = TRI_XY(0,0); cop->src_end_xy = TRI_XY(w - 1, h_this - 1); if (mode == MODE_IMAGE) { while (h_this--) { w_remain = w; src = srcLine; srcLine += srcStride; off = offLine; offLine += offStride; while (w_remain--) *off++ = *src++; } } else { while (h_this--) { w_remain = w; msk = mskLine; mskLine += mskStride; off = offLine; offLine += offStride; while (w_remain--) *off++ = rgb | (*msk++ << 24); } } cop->command = (COP_OP_BLT | COP_SCL_OPAQUE | COP_OP_FB); } pbox++; } cop->src_offset = 0; KdMarkSync (pDst->pDrawable->pScreen); } else { KdCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); } }
void SafeAlphaComposite (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { RegionRec region; int n; BoxPtr pbox; CompositeFunc func = 0; Bool srcRepeat = pSrc->repeat; Bool maskRepeat = FALSE; Bool srcAlphaMap = pSrc->alphaMap != 0; Bool maskAlphaMap = FALSE; Bool dstAlphaMap = pDst->alphaMap != 0; int x_msk, y_msk, x_src, y_src, x_dst, y_dst; int w, h, w_this, h_this; int dstDepth = pDst->pDrawable->depth; int oldFormat = pDst->format; 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; maskRepeat = pMask->repeat; maskAlphaMap = pMask->alphaMap != 0; } /* * We can use the more optimized fbpict code, but it sets bits above * the depth to zero. Temporarily adjust destination depth if needed. */ if (pDst->pDrawable->type == DRAWABLE_WINDOW && pDst->pDrawable->depth == 24 && pDst->pDrawable->bitsPerPixel == 32) { pDst->pDrawable->depth = 32; } /* For rootless preserve the alpha in x8r8g8b8 which really is * a8r8g8b8 */ if (oldFormat == PICT_x8r8g8b8) { pDst->format = PICT_a8r8g8b8; } if (!pSrc->transform && !(pMask && pMask->transform)) if (!maskAlphaMap && !srcAlphaMap && !dstAlphaMap) switch (op) { case PictOpSrc: #ifdef USE_MMX if (!pMask && pSrc->format == pDst->format && pSrc->pDrawable != pDst->pDrawable) { func = fbCompositeCopyAreammx; } #endif break; case PictOpOver: if (pMask) { if (srcRepeat && pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1) { srcRepeat = FALSE; if (PICT_FORMAT_COLOR(pSrc->format)) { switch (pMask->format) { case PICT_a8: switch (pDst->format) { case PICT_r5g6b5: case PICT_b5g6r5: #ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSolidMask_nx8x0565mmx; else #endif func = fbCompositeSolidMask_nx8x0565; break; case PICT_r8g8b8: case PICT_b8g8r8: func = fbCompositeSolidMask_nx8x0888; break; case PICT_a8r8g8b8: case PICT_x8r8g8b8: case PICT_a8b8g8r8: case PICT_x8b8g8r8: func = SafeAlphaCompositeSolidMask_nx8x8888; break; } break; case PICT_a8r8g8b8: if (pMask->componentAlpha) { switch (pDst->format) { case PICT_a8r8g8b8: case PICT_x8r8g8b8: #ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSolidMask_nx8888x8888Cmmx; else #endif func = fbCompositeSolidMask_nx8888x8888C; break; case PICT_r5g6b5: #ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSolidMask_nx8888x0565Cmmx; else #endif func = fbCompositeSolidMask_nx8888x0565C; break; } } break; case PICT_a8b8g8r8: if (pMask->componentAlpha) { switch (pDst->format) { case PICT_a8b8g8r8: case PICT_x8b8g8r8: #ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSolidMask_nx8888x8888Cmmx; else #endif func = fbCompositeSolidMask_nx8888x8888C; break; case PICT_b5g6r5: #ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSolidMask_nx8888x0565Cmmx; else #endif func = fbCompositeSolidMask_nx8888x0565C; break; } } break; case PICT_a1: switch (pDst->format) { case PICT_r5g6b5: case PICT_b5g6r5: case PICT_r8g8b8: case PICT_b8g8r8: case PICT_a8r8g8b8: case PICT_x8r8g8b8: case PICT_a8b8g8r8: case PICT_x8b8g8r8: func = fbCompositeSolidMask_nx1xn; break; } break; } } } else /* has mask and non-repeating source */ { if (pSrc->pDrawable == pMask->pDrawable && xSrc == xMask && ySrc == yMask && !pMask->componentAlpha) { /* source == mask: non-premultiplied data */ switch (pSrc->format) { case PICT_x8b8g8r8: switch (pMask->format) { case PICT_a8r8g8b8: case PICT_a8b8g8r8: switch (pDst->format) { case PICT_a8r8g8b8: case PICT_x8r8g8b8: #ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSrc_8888RevNPx8888mmx; #endif break; case PICT_r5g6b5: #ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSrc_8888RevNPx0565mmx; #endif break; } break; } break; case PICT_x8r8g8b8: switch (pMask->format) { case PICT_a8r8g8b8: case PICT_a8b8g8r8: switch (pDst->format) { case PICT_a8b8g8r8: case PICT_x8b8g8r8: #ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSrc_8888RevNPx8888mmx; #endif break; case PICT_r5g6b5: #ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSrc_8888RevNPx0565mmx; #endif break; } break; } break; } break; } else { /* non-repeating source, repeating mask => translucent window */ if (maskRepeat && pMask->pDrawable->width == 1 && pMask->pDrawable->height == 1) { if (pSrc->format == PICT_x8r8g8b8 && pDst->format == PICT_x8r8g8b8 && pMask->format == PICT_a8) { #ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSrc_8888x8x8888mmx; #endif } } } } } else /* no mask */ { if (srcRepeat && pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1) { /* no mask and repeating source */ switch (pSrc->format) { case PICT_a8r8g8b8: switch (pDst->format) { case PICT_a8r8g8b8: case PICT_x8r8g8b8: #ifdef USE_MMX if (fbHaveMMX()) { srcRepeat = FALSE; func = fbCompositeSolid_nx8888mmx; } #endif break; case PICT_r5g6b5: #ifdef USE_MMX if (fbHaveMMX()) { srcRepeat = FALSE; func = fbCompositeSolid_nx0565mmx; } #endif break; } break; } } else { switch (pSrc->format) { case PICT_a8r8g8b8: switch (pDst->format) { case PICT_a8r8g8b8: case PICT_x8r8g8b8: #ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSrc_8888x8888mmx; else #endif func = fbCompositeSrc_8888x8888; break; case PICT_r8g8b8: func = fbCompositeSrc_8888x0888; break; case PICT_r5g6b5: func = fbCompositeSrc_8888x0565; break; } break; case PICT_x8r8g8b8: switch (pDst->format) { case PICT_a8r8g8b8: case PICT_x8r8g8b8: #ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeCopyAreammx; #endif break; } case PICT_x8b8g8r8: switch (pDst->format) { case PICT_a8b8g8r8: case PICT_x8b8g8r8: #ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeCopyAreammx; #endif break; } break; case PICT_a8b8g8r8: switch (pDst->format) { case PICT_a8b8g8r8: case PICT_x8b8g8r8: #ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSrc_8888x8888mmx; else #endif func = fbCompositeSrc_8888x8888; break; case PICT_b8g8r8: func = fbCompositeSrc_8888x0888; break; case PICT_b5g6r5: func = fbCompositeSrc_8888x0565; break; } break; case PICT_r5g6b5: switch (pDst->format) { case PICT_r5g6b5: func = fbCompositeSrc_0565x0565; break; } break; case PICT_b5g6r5: switch (pDst->format) { case PICT_b5g6r5: func = fbCompositeSrc_0565x0565; break; } break; } } } break; case PictOpAdd: if (pMask == 0) { switch (pSrc->format) { case PICT_a8r8g8b8: switch (pDst->format) { case PICT_a8r8g8b8: #ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSrcAdd_8888x8888mmx; else #endif func = fbCompositeSrcAdd_8888x8888; break; } break; case PICT_a8b8g8r8: switch (pDst->format) { case PICT_a8b8g8r8: #ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSrcAdd_8888x8888mmx; else #endif func = fbCompositeSrcAdd_8888x8888; break; } break; case PICT_a8: switch (pDst->format) { case PICT_a8: #ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSrcAdd_8000x8000mmx; else #endif func = fbCompositeSrcAdd_8000x8000; break; } break; case PICT_a1: switch (pDst->format) { case PICT_a1: func = fbCompositeSrcAdd_1000x1000; break; } break; } } break; } if (!func) { /* no fast path, use the general code */ fbCompositeGeneral(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); // Reset destination depth and format to their true value pDst->pDrawable->depth = dstDepth; pDst->format = oldFormat; return; } if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) return; n = REGION_NUM_RECTS (®ion); pbox = REGION_RECTS (®ion); while (n--) { h = pbox->y2 - pbox->y1; y_src = pbox->y1 - yDst + ySrc; y_msk = pbox->y1 - yDst + yMask; y_dst = pbox->y1; while (h) { h_this = h; w = pbox->x2 - pbox->x1; x_src = pbox->x1 - xDst + xSrc; x_msk = pbox->x1 - xDst + xMask; x_dst = pbox->x1; if (maskRepeat) { y_msk = mod (y_msk, pMask->pDrawable->height); if (h_this > pMask->pDrawable->height - y_msk) h_this = pMask->pDrawable->height - y_msk; } if (srcRepeat) { y_src = mod (y_src, pSrc->pDrawable->height); if (h_this > pSrc->pDrawable->height - y_src) h_this = pSrc->pDrawable->height - y_src; } while (w) { w_this = w; if (maskRepeat) { x_msk = mod (x_msk, pMask->pDrawable->width); if (w_this > pMask->pDrawable->width - x_msk) w_this = pMask->pDrawable->width - x_msk; } if (srcRepeat) { x_src = mod (x_src, pSrc->pDrawable->width); if (w_this > pSrc->pDrawable->width - x_src) w_this = pSrc->pDrawable->width - x_src; } (*func) (op, pSrc, pMask, pDst, x_src, y_src, x_msk, y_msk, x_dst, y_dst, w_this, h_this); w -= w_this; x_src += w_this; x_msk += w_this; x_dst += w_this; } h -= h_this; y_src += h_this; y_msk += h_this; y_dst += h_this; } pbox++; } REGION_UNINIT (pDst->pDrawable->pScreen, ®ion); // Reset destination depth/format to its true value pDst->pDrawable->depth = dstDepth; pDst->format = oldFormat; }
Bool xglCompositeGeneral (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, xglGeometryPtr pGeometry, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { ScreenPtr pScreen = pDst->pDrawable->pScreen; INT16 xOff, yOff; glitz_surface_t *src, *mask = NULL, *dst; int dstXoff, dstYoff; RegionRec region; BoxPtr pBox, pExt; int nBox; if (pDst->alphaMap) return FALSE; if (op >= NUM_XGL_OPERATORS) return FALSE; if (pSrc->pDrawable) { if (pSrc->pDrawable->type != DRAWABLE_PIXMAP) return FALSE; if (pSrc->pDrawable->bitsPerPixel == 1) return FALSE; } if (pMask) { if (pMask->pDrawable) { if (pMask->pDrawable->type != DRAWABLE_PIXMAP) return FALSE; if (pSrc->pDrawable == pMask->pDrawable && pSrc != pMask) return FALSE; } } if (!xglPrepareTarget (pDst->pDrawable)) return FALSE; if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) return TRUE; pBox = REGION_RECTS (®ion); nBox = REGION_NUM_RECTS (®ion); pExt = REGION_EXTENTS (pScreen, ®ion); XGL_GET_DRAWABLE (pDst->pDrawable, dst, dstXoff, dstYoff); if (!xglSyncPicture (pScreen, pSrc, pExt->x1 + xSrc - xDst, pExt->y1 + ySrc - yDst, pExt->x2 - pExt->x1, pExt->y2 - pExt->y1, &xOff, &yOff)) { REGION_UNINIT (pScreen, ®ion); return FALSE; } xSrc -= xOff; ySrc -= yOff; XGL_GET_SOURCE_PICTURE (pSrc, src); if (pMask) { /* bitmap as mask */ if (pMask->pDrawable && pMask->pDrawable->bitsPerPixel == 1) { if (pGeometry) { REGION_UNINIT (pScreen, ®ion); return FALSE; } pGeometry = xglPixmapToGeometry ((PixmapPtr) pMask->pDrawable, xDst - xMask, yDst - yMask); if (!pGeometry) { REGION_UNINIT (pScreen, ®ion); return FALSE; } } else { if (!xglSyncPicture (pScreen, pMask, pExt->x1 + xMask - xDst, pExt->y1 + yMask - yDst, pExt->x2 - pExt->x1, pExt->y2 - pExt->y1, &xOff, &yOff)) { REGION_UNINIT (pScreen, ®ion); return FALSE; } xMask -= xOff; yMask -= yOff; XGL_GET_SOURCE_PICTURE (pMask, mask); } } if (!pGeometry) { if (!pSrc->transform && pSrc->filter != PictFilterConvolution) { if (pSrc->pDrawable && pSrc->repeat == RepeatNormal) { XGL_PIXMAP_PRIV ((PixmapPtr) pSrc->pDrawable); /* tile */ if (!pPixmapPriv->acceleratedTile) { pGeometry = xglTiledBoxGeometry ((PixmapPtr) pSrc->pDrawable, xSrc - xDst, ySrc - yDst, pBox, nBox); if (!pGeometry) { REGION_UNINIT (pScreen, ®ion); return FALSE; } pBox = pExt; nBox = 1; } } else { /* copy */ if (op == PictOpSrc && !mask) { if (xglCopy (pSrc->pDrawable, pDst->pDrawable, xSrc - xDst, ySrc - yDst, pBox, nBox)) { REGION_UNINIT (pScreen, ®ion); return TRUE; } } } } if (nBox > 1) { pGeometry = xglGetScratchVertexGeometry (pScreen, 4 * nBox); GEOMETRY_ADD_BOX (pScreen, pGeometry, pBox, nBox); pBox = pExt; } xSrc += pBox->x1 - xDst; ySrc += pBox->y1 - yDst; if (pMask) { xMask += pBox->x1 - xDst; yMask += pBox->y1 - yDst; } xDst = pBox->x1; yDst = pBox->y1; width = pBox->x2 - pBox->x1; height = pBox->y2 - pBox->y1; } else { glitz_surface_set_clip_region (dst, dstXoff, dstYoff, (glitz_box_t *) pBox, nBox); } if (pGeometry) { GEOMETRY_TRANSLATE (pGeometry, dstXoff, dstYoff); if (!GEOMETRY_ENABLE (pGeometry, dst)) { REGION_UNINIT (pScreen, ®ion); return FALSE; } } else GEOMETRY_DISABLE (dst); glitz_composite (XGL_OPERATOR (op), src, mask, dst, xSrc, ySrc, xMask, yMask, xDst + dstXoff, yDst + dstYoff, width, height); glitz_surface_set_clip_region (dst, 0, 0, NULL, 0); REGION_UNINIT (pScreen, ®ion); if (glitz_surface_get_status (dst)) return FALSE; return TRUE; }
void fbWalkCompositeRegion (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height, Bool srcRepeat, Bool maskRepeat, CompositeFunc compositeRect) { RegionRec region; int n; BoxPtr pbox; int w, h, w_this, h_this; int x_msk, y_msk, x_src, y_src, x_dst, y_dst; xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; if (pSrc->pDrawable) { xSrc += pSrc->pDrawable->x; ySrc += pSrc->pDrawable->y; } if (pMask && pMask->pDrawable) { xMask += pMask->pDrawable->x; yMask += pMask->pDrawable->y; } if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) return; n = REGION_NUM_RECTS (®ion); pbox = REGION_RECTS (®ion); while (n--) { h = pbox->y2 - pbox->y1; y_src = pbox->y1 - yDst + ySrc; y_msk = pbox->y1 - yDst + yMask; y_dst = pbox->y1; while (h) { h_this = h; w = pbox->x2 - pbox->x1; x_src = pbox->x1 - xDst + xSrc; x_msk = pbox->x1 - xDst + xMask; x_dst = pbox->x1; if (maskRepeat) { y_msk = mod (y_msk - pMask->pDrawable->y, pMask->pDrawable->height); if (h_this > pMask->pDrawable->height - y_msk) h_this = pMask->pDrawable->height - y_msk; y_msk += pMask->pDrawable->y; } if (srcRepeat) { y_src = mod (y_src - pSrc->pDrawable->y, pSrc->pDrawable->height); if (h_this > pSrc->pDrawable->height - y_src) h_this = pSrc->pDrawable->height - y_src; y_src += pSrc->pDrawable->y; } while (w) { w_this = w; if (maskRepeat) { x_msk = mod (x_msk - pMask->pDrawable->x, pMask->pDrawable->width); if (w_this > pMask->pDrawable->width - x_msk) w_this = pMask->pDrawable->width - x_msk; x_msk += pMask->pDrawable->x; } if (srcRepeat) { x_src = mod (x_src - pSrc->pDrawable->x, pSrc->pDrawable->width); if (w_this > pSrc->pDrawable->width - x_src) w_this = pSrc->pDrawable->width - x_src; x_src += pSrc->pDrawable->x; } (*compositeRect) (op, pSrc, pMask, pDst, x_src, y_src, x_msk, y_msk, x_dst, y_dst, w_this, h_this); w -= w_this; x_src += w_this; x_msk += w_this; x_dst += w_this; } h -= h_this; y_src += h_this; y_msk += h_this; y_dst += h_this; } pbox++; } REGION_UNINIT (pDst->pDrawable->pScreen, ®ion); }