v2: - Require power-of-two bpp in ScreenInit - Eliminate fbCreatePixmapBpp v3 - Squash in the exa and glamor changes so we can remove pRotatedPixmap in the same stroke. Reviewed-by: Eric Anholt <eric@anholt.net> Signed-off-by: Adam Jackson <ajax@redhat.com>
		
			
				
	
	
		
			270 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			270 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			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"
 | 
						|
 | 
						|
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 = xallocarray(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);
 | 
						|
            free(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)
 | 
						|
{
 | 
						|
    return miDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
 | 
						|
                    widthSrc, heightSrc, xOut, yOut, fbCopyNtoN, 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);
 | 
						|
}
 |