Esempio n. 1
0
void 
cfbDoBitblt8To32(
    DrawablePtr pSrc, 
    DrawablePtr pDst, 
    int rop,
    RegionPtr prgnDst, 
    DDXPointPtr pptSrc,
    unsigned long pm,
    unsigned long bitPlane
){
    BoxPtr pbox = REGION_RECTS(prgnDst);
    int nbox = REGION_NUM_RECTS(prgnDst);
    unsigned char *ptr8, *ptr32;
    unsigned char *data8, *data32;
    int pitch8, pitch32;
    int height, width, i;

    cfbGetByteWidthAndPointer(pSrc, pitch8, ptr8);
    cfbGetByteWidthAndPointer(pDst, pitch32, ptr32);
    ptr32 += 3; /* point to the top byte */

    pm >>= 24;

    if((pm == 0xff) && (rop == GXcopy)) {
	for(;nbox; pbox++, pptSrc++, nbox--) {
	    data8 = ptr8 + (pptSrc->y * pitch8) + pptSrc->x;
	    data32 = ptr32 + (pbox->y1 * pitch32) + (pbox->x1 << 2);
	    width = pbox->x2 - pbox->x1;
	    height = pbox->y2 - pbox->y1;

	    while(height--) {
		for(i = 0; i < width; i++)
		    data32[i << 2] = data8[i];
		data8 += pitch8;
		data32 += pitch32;
	    }
	}
    } else {  /* it ain't pretty, but hey */
	for(;nbox; pbox++, pptSrc++, nbox--) {
	    data8 = ptr8 + (pptSrc->y * pitch8) + pptSrc->x;
	    data32 = ptr32 + (pbox->y1 * pitch32) + (pbox->x1 << 2);
	    width = pbox->x2 - pbox->x1;
	    height = pbox->y2 - pbox->y1;

	    while(height--) {	
		switch(rop) {
		case GXcopy:
		    for(i = 0; i < width; i++)
			data32[i<<2] = (data8[i] & pm) | (data32[i<<2] & ~pm);
		    break;
		case GXor:
		    for(i = 0; i < width; i++)
			data32[i<<2] |= data8[i] & pm;
		    break;
		case GXclear:
		    for(i = 0; i < width; i++)
			data32[i<<2] &= ~pm;
		    break;
		case GXand:
		    for(i = 0; i < width; i++) 
			data32[i<<2] &= data8[i] | ~pm;
		    break;
		case GXandReverse:
		    for(i = 0; i < width; i++) 
			data32[i<<2] = ~data32[i<<2] & (data8[i] | ~pm);
		    break;
		case GXandInverted:
		    for(i = 0; i < width; i++) 
			data32[i<<2] &= ~data8[i] | ~pm;
		    break;
		case GXnoop:
		    return;
		case GXxor:
		    for(i = 0; i < width; i++) 
			data32[i<<2] ^= data8[i] & pm;
		    break;
		case GXnor:
		    for(i = 0; i < width; i++)
			data32[i<<2] =  ~(data32[i<<2] | (data8[i] & pm));
		    break;
		case GXequiv:
		    for(i = 0; i < width; i++)
			data32[i<<2] = ~(data32[i<<2] ^ (data8[i] & pm));
		    break;
		case GXinvert:
		    for(i = 0; i < width; i++)
			data32[i<<2] ^= pm;
		    break;
		case GXorReverse:
		    for(i = 0; i < width; i++)
			data32[i<<2] = ~data32[i<<2] | (data8[i] & pm);
		    break;
		case GXcopyInverted:
		    for(i = 0; i < width; i++)
			data32[i<<2] = (~data8[i] & pm) | (data32[i<<2] & ~pm);
		    break;
		case GXorInverted:
		    for(i = 0; i < width; i++)
			data32[i<<2] |= ~data8[i] & pm;
		    break;
		case GXnand:
		    for(i = 0; i < width; i++) 
			data32[i<<2] = ~(data32[i<<2] & (data8[i] | ~pm));
		    break;
		case GXset:
		    for(i = 0; i < width; i++)
			data32[i<<2] |= pm;
		    break;
		}
	        data8 += pitch8;
	        data32 += pitch32;
	    }
	}
    }
}
Esempio n. 2
0
RegionPtr
CreatorCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
		GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty)
{
	FFBPtr pFfb = GET_FFB_FROM_SCREEN (pDstDrawable->pScreen);
	ffb_fbcPtr ffb = pFfb->regs;
	RegionPtr ret;
	unsigned char *dptr, *sptr, *sfb;
	int garbage, all_planes;
	
	cfbGetByteWidthAndPointer (pDstDrawable, garbage, dptr);
	cfbGetByteWidthAndPointer (pSrcDrawable, garbage, sptr);
	if (pSrcDrawable->bitsPerPixel == 8) {
		sfb = (unsigned char *) pFfb->sfb8r;
		all_planes = 0xff;
	} else {
		sfb = (unsigned char *) pFfb->sfb32;
		all_planes = 0xffffff;
	}

	FFBLOG(("CreatorCopyArea: SFB(%p) s(%p) d(%p) alu(%x) pmsk(%08x) "
		"src(%08x:%08x) dst(%08x:%08x)\n",
		sfb, sptr, dptr, pGC->alu, pGC->planemask,
		srcx, srcy, dstx, dsty));
	if (((pGC->planemask & all_planes) != all_planes || pGC->alu != GXcopy) &&
	    dptr != sfb) {
		if(sptr == sfb) {
			WindowPtr pWin = (WindowPtr) pSrcDrawable;

			FFB_ATTR_SFB_VAR_WIN(pFfb, pGC->planemask, pGC->alu, pWin);
			FFBWait(pFfb, ffb);
		}
		if (pSrcDrawable->bitsPerPixel == 8)
			return cfbCopyArea (pSrcDrawable, pDstDrawable,
					    pGC, srcx, srcy, width, height, dstx, dsty);
		else
			return cfb32CopyArea (pSrcDrawable, pDstDrawable,
					      pGC, srcx, srcy, width, height, dstx, dsty);
	}

	/* Try to use hw VSCROLL if possible */
	if (!pFfb->disable_vscroll &&	/* must not be ffb1 in hires */
	    pGC->alu == GXcopy &&	/* it must be a copy */
	    dstx == srcx &&		/* X must be unchanging */
	    dsty != srcy &&		/* Y must be changing */
	    sptr == dptr &&		/* src and dst must be the framebuffer */
	    dptr == sfb) {
		WindowPtr pWin = (WindowPtr) pSrcDrawable;
		CreatorPrivWinPtr pFfbPrivWin = CreatorGetWindowPrivate(pWin);
		unsigned int fbc = pFfbPrivWin->fbc_base;
		int same_buffer;

		/* One last check, the read buffer and the write buffer
		 * must be the same.  VSCROLL only allows to move pixels
		 * within the same buffer.
		 */
		if (!pFfb->has_double_buffer) {
			same_buffer = 1;
		} else {
			same_buffer = 0;
			if ((((fbc & FFB_FBC_WB_MASK) == FFB_FBC_WB_A) &&
			     ((fbc & FFB_FBC_RB_MASK) == FFB_FBC_RB_A)) ||
			    (((fbc & FFB_FBC_WB_MASK) == FFB_FBC_WB_B) &&
			     ((fbc & FFB_FBC_RB_MASK) == FFB_FBC_RB_B)))
				same_buffer = 1;
		}

		if (same_buffer != 0) {
			FFB_ATTR_VSCROLL_WIN(pFfb, pGC->planemask, pWin);
			if (pSrcDrawable->bitsPerPixel == 8)
				ret = cfbBitBlt (pSrcDrawable, pDstDrawable,
						 pGC, srcx, srcy, width, height,
						 dstx, dsty,
						 (void (*)())CreatorDoVertBitblt, 0);
			else
				ret = cfb32BitBlt (pSrcDrawable, pDstDrawable,
						   pGC, srcx, srcy, width, height,
						   dstx, dsty,
						   (void (*)())CreatorDoVertBitblt, 0);
			FFBLOG(("CreatorCopyArea: Done, returning %p\n", ret));
			return ret;
		}
	}

	/* OK, we have to use GCOPY. */

	/* Even when we are only reading from the framebuffer, we must
	 * set the SFB_VAR attributes to handle double-buffering correctly.
	 */
	if(dptr == sfb || sptr == sfb) {
		WindowPtr pWin;

		if (dptr == sfb)
			pWin = (WindowPtr) pDstDrawable;
		else
			pWin = (WindowPtr) pSrcDrawable;
		FFB_ATTR_SFB_VAR_WIN(pFfb, pGC->planemask, pGC->alu, pWin);
		FFBWait(pFfb, ffb);
	}
	if (pSrcDrawable->bitsPerPixel == 8)
		ret = cfbBitBlt (pSrcDrawable, pDstDrawable,
				 pGC, srcx, srcy, width, height,
				 dstx, dsty, (void (*)())CreatorDoBitblt, 0);
	else
		ret = cfb32BitBlt (pSrcDrawable, pDstDrawable,
				   pGC, srcx, srcy, width, height,
				   dstx, dsty, (void (*)())CreatorDoBitblt, 0);

	FFBLOG(("CreatorCopyArea: Done, returning %p\n", ret));
	return ret;
}
Esempio n. 3
0
static void
cfb8_32DoBitBlt(
    DrawablePtr	    pSrc, 
    DrawablePtr	    pDst,
    RegionPtr	    prgnDst,
    DDXPointPtr	    pptSrc,
    void	    (*DoBlt)() 
){
    int nbox, careful, SrcPitch, DstPitch;
    BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
    DDXPointPtr pptTmp, pptNew1, pptNew2;
    int xdir, ydir;
    unsigned char *SrcPtr, *DstPtr;

    /* XXX we have to err on the side of safety when both are windows,
     * because we don't know if IncludeInferiors is being used.
     */
    careful = ((pSrc == pDst) ||
               ((pSrc->type == DRAWABLE_WINDOW) &&
                (pDst->type == DRAWABLE_WINDOW)));

    pbox = REGION_RECTS(prgnDst);
    nbox = REGION_NUM_RECTS(prgnDst);

    pboxNew1 = NULL;
    pptNew1 = NULL;
    pboxNew2 = NULL;
    pptNew2 = NULL;
    if (careful && (pptSrc->y < pbox->y1)) {
        /* walk source botttom to top */
	ydir = -1;

	if (nbox > 1) {
	    /* keep ordering in each band, reverse order of bands */
	    pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
	    if(!pboxNew1)
		return;
	    pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
	    if(!pptNew1) {
	        DEALLOCATE_LOCAL(pboxNew1);
	        return;
	    }
	    pboxBase = pboxNext = pbox+nbox-1;
	    while (pboxBase >= pbox) {
	        while ((pboxNext >= pbox) &&
		       (pboxBase->y1 == pboxNext->y1))
		    pboxNext--;
	        pboxTmp = pboxNext+1;
	        pptTmp = pptSrc + (pboxTmp - pbox);
	        while (pboxTmp <= pboxBase) {
		    *pboxNew1++ = *pboxTmp++;
		    *pptNew1++ = *pptTmp++;
	        }
	        pboxBase = pboxNext;
	    }
	    pboxNew1 -= nbox;
	    pbox = pboxNew1;
	    pptNew1 -= nbox;
	    pptSrc = pptNew1;
        }
    } else {
	/* walk source top to bottom */
	ydir = 1;
    }

    if (careful && (pptSrc->x < pbox->x1)) {
	/* walk source right to left */
        xdir = -1;

	if (nbox > 1) {
	    /* reverse order of rects in each band */
	    pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
	    pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
	    if(!pboxNew2 || !pptNew2) {
		if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
		if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
		if (pboxNew1) {
		    DEALLOCATE_LOCAL(pptNew1);
		    DEALLOCATE_LOCAL(pboxNew1);
		}
	        return;
	    }
	    pboxBase = pboxNext = pbox;
	    while (pboxBase < pbox+nbox) {
	        while ((pboxNext < pbox+nbox) &&
		       (pboxNext->y1 == pboxBase->y1))
		    pboxNext++;
	        pboxTmp = pboxNext;
	        pptTmp = pptSrc + (pboxTmp - pbox);
	        while (pboxTmp != pboxBase) {
		    *pboxNew2++ = *--pboxTmp;
		    *pptNew2++ = *--pptTmp;
	        }
	        pboxBase = pboxNext;
	    }
	    pboxNew2 -= nbox;
	    pbox = pboxNew2;
	    pptNew2 -= nbox;
	    pptSrc = pptNew2;
	}
    } else {
	/* walk source left to right */
        xdir = 1;
    }

    cfbGetByteWidthAndPointer(pSrc, SrcPitch, SrcPtr);
    cfbGetByteWidthAndPointer(pDst, DstPitch, DstPtr);

    (*DoBlt)(SrcPtr,SrcPitch,DstPtr,DstPitch,nbox,pptSrc,pbox,xdir,ydir);
 
    if (pboxNew2) {
	DEALLOCATE_LOCAL(pptNew2);
	DEALLOCATE_LOCAL(pboxNew2);
    }
    if (pboxNew1) {
	DEALLOCATE_LOCAL(pptNew1);
	DEALLOCATE_LOCAL(pboxNew1);
    }

}
Esempio n. 4
0
/* The hw attributes have been set by someone higher up in the call
 * chain.
 */
void
CreatorDoBitblt(DrawablePtr pSrc, DrawablePtr pDst, int alu, RegionPtr prgnDst,
		DDXPointPtr pptSrc, unsigned long planemask)
{
	FFBPtr pFfb = GET_FFB_FROM_SCREEN (pDst->pScreen);
	BoxPtr pboxTmp, pboxNext, pboxBase, pbox;
	DDXPointPtr pptTmp;
	unsigned char *psrcBase, *pdstBase;
	int nbox, widthSrc, widthDst, careful, use_prefetch;
	int psz_shift;

	cfbGetByteWidthAndPointer (pSrc, widthSrc, psrcBase)
	cfbGetByteWidthAndPointer (pDst, widthDst, pdstBase)
	
	careful = ((pSrc == pDst) ||
		  ((pSrc->type == DRAWABLE_WINDOW) &&
		   (pDst->type == DRAWABLE_WINDOW)));
	use_prefetch = (pFfb->use_blkread_prefetch &&
			(psrcBase == (unsigned char *)pFfb->sfb32 ||
			 psrcBase == (unsigned char *)pFfb->sfb8r));

	pbox = REGION_RECTS(prgnDst);
	nbox = REGION_NUM_RECTS(prgnDst);

	pptTmp = pptSrc;
	pboxTmp = pbox;

	FFBLOG(("GCOPY(%d): ", nbox));

	if (pSrc->bitsPerPixel == 8)
		psz_shift = 0;
	else
		psz_shift = 2;

	if (careful && pptSrc->y < pbox->y1) {
		if (pptSrc->x < pbox->x1) {
			/* reverse order of bands and rects in each band */
			pboxTmp=pbox+nbox;
                        pptTmp=pptSrc+nbox;

			while (nbox--){
				pboxTmp--;
				pptTmp--;
				FFBLOG(("[%08x:%08x:%08x:%08x:%08x:%08x] ",
					pptTmp->x, pptTmp->y, pboxTmp->x1, pboxTmp->y1,
					pboxTmp->x2, pboxTmp->y2));
				if (pptTmp->x < pbox->x2) {
					if (use_prefetch) {
						FFBFifo(pFfb, 1);
						pFfb->regs->mer = FFB_MER_EDRA;
						pFfb->rp_active = 1;
						FFBWait(pFfb, pFfb->regs);
					}
					VISmoveImageRL ((psrcBase +
							 ((pptTmp->y + pboxTmp->y2 - pboxTmp->y1 - 1) *
							  widthSrc) +
							 (pptTmp->x << psz_shift)),
				        	        (pdstBase +
							 ((pboxTmp->y2 - 1) * widthDst) +
							 (pboxTmp->x1 << psz_shift)),
					                (pboxTmp->x2 - pboxTmp->x1) << psz_shift,
				        	        (pboxTmp->y2 - pboxTmp->y1),
					                -widthSrc, -widthDst);
				} else {
					if (use_prefetch) {
						FFBFifo(pFfb, 1);
						pFfb->regs->mer = FFB_MER_EIRA;
						pFfb->rp_active = 1;
						FFBWait(pFfb, pFfb->regs);
					}
					VISmoveImageLR ((psrcBase +
							 ((pptTmp->y + pboxTmp->y2 - pboxTmp->y1 - 1) *
							  widthSrc) +
							 (pptTmp->x << psz_shift)),
				        	        (pdstBase +
							 ((pboxTmp->y2 - 1) * widthDst) +
							 (pboxTmp->x1 << psz_shift)),
					                (pboxTmp->x2 - pboxTmp->x1) << psz_shift,
				        	        (pboxTmp->y2 - pboxTmp->y1),
					                -widthSrc, -widthDst);
				}
			}
		} else {
			/* keep ordering in each band, reverse order of bands */
			pboxBase = pboxNext = pbox+nbox-1;

			while (pboxBase >= pbox) {			/* for each band */

				/* find first box in band */
				while (pboxNext >= pbox &&
				       pboxBase->y1 == pboxNext->y1)
					pboxNext--;
		
				pboxTmp = pboxNext+1;			/* first box in band */
				pptTmp = pptSrc + (pboxTmp - pbox);	/* first point in band */
		
				FFBLOG(("[%08x:%08x:%08x:%08x:%08x:%08x] ",
					pptTmp->x, pptTmp->y, pboxTmp->x1, pboxTmp->y1,
					pboxTmp->x2, pboxTmp->y2));
				while (pboxTmp <= pboxBase) {		/* for each box in band */
					if (use_prefetch) {
						FFBFifo(pFfb, 1);
						pFfb->regs->mer = FFB_MER_EIRA;
						pFfb->rp_active = 1;
						FFBWait(pFfb, pFfb->regs);
					}
					VISmoveImageLR ((psrcBase +
							 ((pptTmp->y + pboxTmp->y2 - pboxTmp->y1 - 1) *
							  widthSrc) +
							 (pptTmp->x << psz_shift)),
				        	        (pdstBase +
							 ((pboxTmp->y2 - 1) * widthDst) +
							 (pboxTmp->x1 << psz_shift)),
					                (pboxTmp->x2 - pboxTmp->x1) << psz_shift,
				        	        (pboxTmp->y2 - pboxTmp->y1),
					                -widthSrc, -widthDst);
					++pboxTmp;
					++pptTmp;	
				}
				pboxBase = pboxNext;
			
			}
		}
	} else {
		if (careful && pptSrc->x < pbox->x1) {
			/* reverse order of rects in each band */

			pboxBase = pboxNext = pbox;

			while (pboxBase < pbox+nbox) { /* for each band */

				/* find last box in band */
				while (pboxNext < pbox+nbox &&
				       pboxNext->y1 == pboxBase->y1)
					pboxNext++;

				pboxTmp = pboxNext;			/* last box in band */
				pptTmp = pptSrc + (pboxTmp - pbox);	/* last point in band */

				while (pboxTmp != pboxBase) {		/* for each box in band */
					--pboxTmp;
					--pptTmp;
					FFBLOG(("[%08x:%08x:%08x:%08x:%08x:%08x] ",
						pptTmp->x, pptTmp->y, pboxTmp->x1, pboxTmp->y1,
						pboxTmp->x2, pboxTmp->y2));
					if (pptTmp->x < pbox->x2) {
						if (use_prefetch) {
							FFBFifo(pFfb, 1);
							pFfb->regs->mer = FFB_MER_EDRA;
							pFfb->regs->mer = FFB_MER_EIRA;
							pFfb->rp_active = 1;
						}
						VISmoveImageRL ((psrcBase +
								 (pptTmp->y * widthSrc) +
								 (pptTmp->x << psz_shift)),
						                (pdstBase +
								 (pboxTmp->y1 * widthDst) +
								 (pboxTmp->x1 << psz_shift)),
						                (pboxTmp->x2 - pboxTmp->x1) << psz_shift,
			        	        		(pboxTmp->y2 - pboxTmp->y1),
						                widthSrc, widthDst);
					} else {
						if (use_prefetch) {
							FFBFifo(pFfb, 1);
							pFfb->regs->mer = FFB_MER_EIRA;
							pFfb->rp_active = 1;
							FFBWait(pFfb, pFfb->regs);
						}
						VISmoveImageLR ((psrcBase +
								 (pptTmp->y * widthSrc) +
								 (pptTmp->x << psz_shift)),
						                (pdstBase +
								 (pboxTmp->y1 * widthDst) +
								 (pboxTmp->x1 << psz_shift)),
				                		(pboxTmp->x2 - pboxTmp->x1) << psz_shift,
					        	        (pboxTmp->y2 - pboxTmp->y1),
						                widthSrc, widthDst);
					}
				}
				pboxBase = pboxNext;
			}
		} else {
			while (nbox--) {
				FFBLOG(("[%08x:%08x:%08x:%08x:%08x:%08x] ",
					pptTmp->x, pptTmp->y, pboxTmp->x1, pboxTmp->y1,
					pboxTmp->x2, pboxTmp->y2));
				if (use_prefetch) {
					FFBFifo(pFfb, 1);
					pFfb->regs->mer = FFB_MER_EIRA;
					pFfb->rp_active = 1;
					FFBWait(pFfb, pFfb->regs);
				}
				VISmoveImageLR ((psrcBase +
						 (pptTmp->y * widthSrc) +
						 (pptTmp->x << psz_shift)),
				                (pdstBase +
						 (pboxTmp->y1 * widthDst) +
						 (pboxTmp->x1 << psz_shift)),
				                (pboxTmp->x2 - pboxTmp->x1) << psz_shift,
			        	        (pboxTmp->y2 - pboxTmp->y1),
				                widthSrc, widthDst);
				pboxTmp++;
				pptTmp++;
			}
		}
	}
	if (use_prefetch) {
		FFBFifo(pFfb, 1);
		pFfb->regs->mer = FFB_MER_DRA;
		pFfb->rp_active = 1;
		FFBWait(pFfb, pFfb->regs);
	}
	FFBLOG(("done\n"));
}