Edit

IABSD.fr/xenocara/xserver/fb/fbcopy.c

Branch :

  • Show log

    Commit

  • Author : matthieu
    Date : 2010-07-27 19:02:24
    Hash : 95d684a0
    Message : Update to xserver 1.8. Tested by many. Ok oga@, todd@.

  • xserver/fb/fbcopy.c
  • /*
     * Copyright © 1998 Keith Packard
     *
     * Permission to use, copy, modify, distribute, and sell this software and its
     * documentation for any purpose is hereby granted without fee, provided that
     * the above copyright notice appear in all copies and that both that
     * copyright notice and this permission notice appear in supporting
     * documentation, and that the name of Keith Packard not be used in
     * advertising or publicity pertaining to distribution of the software without
     * specific, written prior permission.  Keith Packard makes no
     * representations about the suitability of this software for any purpose.  It
     * is provided "as is" without express or implied warranty.
     *
     * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     * PERFORMANCE OF THIS SOFTWARE.
     */
    
    #ifdef HAVE_DIX_CONFIG_H
    #include <dix-config.h>
    #endif
    
    #include <stdlib.h>
    
    #include "fb.h"
    
    /* Compatibility wrapper, to be removed at next ABI change. */
    void
    fbCopyRegion (DrawablePtr   pSrcDrawable,
                 DrawablePtr   pDstDrawable,
                 GCPtr         pGC,
                 RegionPtr     pDstRegion,
                 int           dx,
                 int           dy,
                 fbCopyProc    copyProc,
                 Pixel         bitPlane,
                 void          *closure)
    {
        miCopyRegion(pSrcDrawable, pDstDrawable, pGC, pDstRegion, dx, dy, copyProc, bitPlane, closure);
    }
    
    /* Compatibility wrapper, to be removed at next ABI change. */
    RegionPtr
    fbDoCopy (DrawablePtr  pSrcDrawable,
             DrawablePtr   pDstDrawable,
             GCPtr         pGC,
             int           xIn,
             int           yIn,
             int           widthSrc,
             int           heightSrc,
             int           xOut,
             int           yOut,
             fbCopyProc    copyProc,
             Pixel         bitPlane,
             void          *closure)
    {
        return miDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut, copyProc, bitPlane, closure);
    }
    
    void
    fbCopyNtoN (DrawablePtr	pSrcDrawable,
    	    DrawablePtr	pDstDrawable,
    	    GCPtr	pGC,
    	    BoxPtr	pbox,
    	    int		nbox,
    	    int		dx,
    	    int		dy,
    	    Bool	reverse,
    	    Bool	upsidedown,
    	    Pixel	bitplane,
    	    void	*closure)
    {
        CARD8	alu = pGC ? pGC->alu : GXcopy;
        FbBits	pm = pGC ? fbGetGCPrivate(pGC)->pm : FB_ALLONES;
        FbBits	*src;
        FbStride	srcStride;
        int		srcBpp;
        int		srcXoff, srcYoff;
        FbBits	*dst;
        FbStride	dstStride;
        int		dstBpp;
        int		dstXoff, dstYoff;
        
        fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
        fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
    
        while (nbox--)
        {
    #ifndef FB_ACCESS_WRAPPER /* pixman_blt() doesn't support accessors yet */
    	if (pm == FB_ALLONES && alu == GXcopy && !reverse &&
    	    !upsidedown)
    	{
    	    if (!pixman_blt ((uint32_t *)src, (uint32_t *)dst, srcStride, dstStride, srcBpp, dstBpp,
    			     (pbox->x1 + dx + srcXoff),
    			     (pbox->y1 + dy + srcYoff),
    			     (pbox->x1 + dstXoff),
    			     (pbox->y1 + dstYoff),
    			     (pbox->x2 - pbox->x1),
    			     (pbox->y2 - pbox->y1)))
    		goto fallback;
    	    else
    		goto next;
    	}
        fallback:
    #endif
    	fbBlt (src + (pbox->y1 + dy + srcYoff) * srcStride,
    	       srcStride,
    	       (pbox->x1 + dx + srcXoff) * srcBpp,
    	       
    	       dst + (pbox->y1 + dstYoff) * dstStride,
    	       dstStride,
    	       (pbox->x1 + dstXoff) * dstBpp,
    	       
    	       (pbox->x2 - pbox->x1) * dstBpp,
    	       (pbox->y2 - pbox->y1),
    	       
    	       alu,
    	       pm,
    	       dstBpp,
    	       
    	       reverse,
    	       upsidedown);
    #ifndef FB_ACCESS_WRAPPER
        next:
    #endif
    	pbox++;
        }    
        fbFinishAccess (pDstDrawable);
        fbFinishAccess (pSrcDrawable);
    }
    
    void
    fbCopy1toN (DrawablePtr	pSrcDrawable,
    	    DrawablePtr	pDstDrawable,
    	    GCPtr	pGC,
    	    BoxPtr	pbox,
    	    int		nbox,
    	    int		dx,
    	    int		dy,
    	    Bool	reverse,
    	    Bool	upsidedown,
    	    Pixel	bitplane,
    	    void	*closure)
    {
        FbGCPrivPtr	pPriv = fbGetGCPrivate(pGC);
        FbBits	*src;
        FbStride	srcStride;
        int		srcBpp;
        int		srcXoff, srcYoff;
        FbBits	*dst;
        FbStride	dstStride;
        int		dstBpp;
        int		dstXoff, dstYoff;
    
        fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
        fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
    
        while (nbox--)
        {
    	if (dstBpp == 1)
    	{
    	    fbBlt (src + (pbox->y1 + dy + srcYoff) * srcStride,
    		   srcStride,
    		   (pbox->x1 + dx + srcXoff) * srcBpp,
        
    		   dst + (pbox->y1 + dstYoff) * dstStride,
    		   dstStride,
    		   (pbox->x1 + dstXoff) * dstBpp,
        
    		   (pbox->x2 - pbox->x1) * dstBpp,
    		   (pbox->y2 - pbox->y1),
        
    		   FbOpaqueStipple1Rop(pGC->alu,
    				       pGC->fgPixel,pGC->bgPixel),
    		   pPriv->pm,
    		   dstBpp,
        
    		   reverse,
    		   upsidedown);
    	}
    	else
    	{
    	    fbBltOne ((FbStip *) (src + (pbox->y1 + dy + srcYoff) * srcStride),
    		      srcStride*(FB_UNIT/FB_STIP_UNIT),
    		      (pbox->x1 + dx + srcXoff),
        
    		      dst + (pbox->y1 + dstYoff) * dstStride,
    		      dstStride,
    		      (pbox->x1 + dstXoff) * dstBpp,
    		      dstBpp,
        
    		      (pbox->x2 - pbox->x1) * dstBpp,
    		      (pbox->y2 - pbox->y1),
        
    		      pPriv->and, pPriv->xor,
    		      pPriv->bgand, pPriv->bgxor);
    	}
    	pbox++;
        }
    
        fbFinishAccess (pDstDrawable);
        fbFinishAccess (pSrcDrawable);
    }
    
    void
    fbCopyNto1 (DrawablePtr	pSrcDrawable,
    	    DrawablePtr	pDstDrawable,
    	    GCPtr	pGC,
    	    BoxPtr	pbox,
    	    int		nbox,
    	    int		dx,
    	    int		dy,
    	    Bool	reverse,
    	    Bool	upsidedown,
    	    Pixel	bitplane,
    	    void	*closure)
    {
        FbGCPrivPtr	pPriv = fbGetGCPrivate (pGC);
        
        while (nbox--)
        {
    	if (pDstDrawable->bitsPerPixel == 1)
    	{
    	    FbBits	*src;
    	    FbStride    srcStride;
    	    int		srcBpp;
    	    int		srcXoff, srcYoff;
        
    	    FbStip	*dst;
    	    FbStride    dstStride;
    	    int		dstBpp;
    	    int		dstXoff, dstYoff;
    	    
    	    fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
    	    fbGetStipDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
    	    fbBltPlane (src + (pbox->y1+ dy + srcYoff) * srcStride,
    			srcStride,
    			(pbox->x1 + dx + srcXoff) * srcBpp,
    			srcBpp,
        
    			dst + (pbox->y1 + dstYoff) * dstStride,
    			dstStride,
    			(pbox->x1 + dstXoff) * dstBpp,
        
    			(pbox->x2 - pbox->x1) * srcBpp,
    			(pbox->y2 - pbox->y1),
        
    			(FbStip) pPriv->and, (FbStip) pPriv->xor,
    			(FbStip) pPriv->bgand, (FbStip) pPriv->bgxor,
    			bitplane);
    	    fbFinishAccess (pDstDrawable);
    	    fbFinishAccess (pSrcDrawable);
    	}
    	else
    	{
    	    FbBits	*src;
    	    FbStride    srcStride;
    	    int		srcBpp;
    	    int         srcXoff, srcYoff;
    
    	    FbBits	*dst;
    	    FbStride    dstStride;
    	    int		dstBpp;
    	    int		dstXoff, dstYoff;
        
    	    FbStip	*tmp;
    	    FbStride    tmpStride;
    	    int		width, height;
    	    
    	    width = pbox->x2 - pbox->x1;
    	    height = pbox->y2 - pbox->y1;
    	    
    	    tmpStride = ((width + FB_STIP_MASK) >> FB_STIP_SHIFT);
    	    tmp = xalloc (tmpStride * height * sizeof (FbStip));
    	    if (!tmp)
    		return;
    	    
    	    fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
    	    fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
    	    
    	    fbBltPlane (src + (pbox->y1+ dy + srcYoff) * srcStride,
    			srcStride,
    			(pbox->x1 + dx + srcXoff) * srcBpp,
    			srcBpp,
        
    			tmp,
    			tmpStride,
    			0,
        
    			width * srcBpp,
    			height,
        
    			fbAndStip(GXcopy,FB_ALLONES,FB_ALLONES),
    			fbXorStip(GXcopy,FB_ALLONES,FB_ALLONES),
    			fbAndStip(GXcopy,0,FB_ALLONES),
    			fbXorStip(GXcopy,0,FB_ALLONES),
    			bitplane);
    	    fbBltOne (tmp,
    		      tmpStride,
    		      0,
        
    		      dst + (pbox->y1 + dstYoff) * dstStride,
    		      dstStride,
    		      (pbox->x1 + dstXoff) * dstBpp,
    		      dstBpp,
        
    		      width * dstBpp,
    		      height,
        
    		      pPriv->and, pPriv->xor,
    		      pPriv->bgand, pPriv->bgxor);
    	    xfree (tmp);
    
    	    fbFinishAccess (pDstDrawable);
    	    fbFinishAccess (pSrcDrawable);
    	}
    	pbox++;
        }
    }
    
    RegionPtr
    fbCopyArea (DrawablePtr	pSrcDrawable,
    	    DrawablePtr	pDstDrawable,
    	    GCPtr	pGC,
    	    int		xIn, 
    	    int		yIn,
    	    int		widthSrc, 
    	    int		heightSrc,
    	    int		xOut, 
    	    int		yOut)
    {
        miCopyProc	copy;
    
    #ifdef FB_24_32BIT
        if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel)
    	copy = fb24_32CopyMtoN;
        else
    #endif
    	copy = fbCopyNtoN;
        return miDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
    		     widthSrc, heightSrc, xOut, yOut, copy, 0, 0);
    }
    
    RegionPtr
    fbCopyPlane (DrawablePtr    pSrcDrawable,
    	     DrawablePtr    pDstDrawable,
    	     GCPtr	    pGC,
    	     int	    xIn, 
    	     int	    yIn,
    	     int	    widthSrc, 
    	     int	    heightSrc,
    	     int	    xOut, 
    	     int	    yOut,
    	     unsigned long  bitplane)
    {
        if (pSrcDrawable->bitsPerPixel > 1)
    	return miDoCopy (pSrcDrawable, pDstDrawable, pGC,
    			 xIn, yIn, widthSrc, heightSrc,
    			 xOut, yOut, fbCopyNto1, (Pixel) bitplane, 0);
        else if (bitplane & 1)
    	return miDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
    			 widthSrc, heightSrc, xOut, yOut, fbCopy1toN,
    			 (Pixel) bitplane, 0);
        else
    	return miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
    				 xIn, yIn,
    				 widthSrc,
    				 heightSrc,
    				 xOut, yOut, bitplane);
    }