Exemplo n.º 1
0
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(&region);

    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(&region, 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(&region, pDst->pDrawable->x + xoff,
                        pDst->pDrawable->y + yoff);
        dstReg = &region;
    }

    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(&region);
    return TRUE;
}
Exemplo n.º 2
0
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 (&region,
				       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 (&region);
	pbox = REGION_RECTS (&region);
	
	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);
    }
}
Exemplo n.º 3
0
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 (&region,
                                   pSrc,
                                   pMask,
                                   pDst,
                                   xSrc,
                                   ySrc,
                                   xMask,
                                   yMask,
                                   xDst,
                                   yDst,
                                   width,
                                   height))
        return;

    n = REGION_NUM_RECTS (&region);
    pbox = REGION_RECTS (&region);
    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, &region);

    // Reset destination depth/format to its true value
    pDst->pDrawable->depth = dstDepth;
    pDst->format = oldFormat;
}
Exemplo n.º 4
0
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 (&region, pSrc, pMask, pDst,
				   xSrc, ySrc, xMask, yMask,
				   xDst, yDst, width, height))
	return TRUE;

    pBox = REGION_RECTS (&region);
    nBox = REGION_NUM_RECTS (&region);
    pExt = REGION_EXTENTS (pScreen, &region);

    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, &region);
	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, &region);
		return FALSE;
	    }

	    pGeometry = xglPixmapToGeometry ((PixmapPtr) pMask->pDrawable,
					     xDst - xMask,
					     yDst - yMask);
	    if (!pGeometry)
	    {
		REGION_UNINIT (pScreen, &region);
		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, &region);
		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, &region);
			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, &region);
			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, &region);
	    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, &region);

    if (glitz_surface_get_status (dst))
	return FALSE;

    return TRUE;
}
Exemplo n.º 5
0
Arquivo: fbpict.c Projeto: hush-z/VMGL
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 (&region, pSrc, pMask, pDst, xSrc, ySrc,
                                   xMask, yMask, xDst, yDst, width, height))
        return;

    n = REGION_NUM_RECTS (&region);
    pbox = REGION_RECTS (&region);
    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, &region);
}