xaaCpyPlane.c revision 706f2543
1
2/*
3   A CopyPlane function that handles bitmap->screen copies and
4   sends anything else to the Fallback.
5
6   Also, a PushPixels for solid fill styles.
7
8   Written by Mark Vojkovich (markv@valinux.com)
9
10*/
11
12#ifdef HAVE_XORG_CONFIG_H
13#include <xorg-config.h>
14#endif
15
16#include <string.h>
17
18#include "misc.h"
19#include "xf86.h"
20#include "xf86_OSproc.h"
21#include "servermd.h"
22
23#include <X11/X.h>
24#include "scrnintstr.h"
25#include "mi.h"
26#include "pixmapstr.h"
27#include "xf86str.h"
28#include "xaa.h"
29#include "xaalocal.h"
30#include "xaawrap.h"
31
32static void XAACopyPlane1toNColorExpand(DrawablePtr pSrc, DrawablePtr pDst,
33					GCPtr pGC, RegionPtr rgnDst,
34					DDXPointPtr pptSrc);
35static void XAACopyPlaneNtoNColorExpand(DrawablePtr pSrc, DrawablePtr pDst,
36					GCPtr pGC, RegionPtr rgnDst,
37					DDXPointPtr pptSrc);
38
39
40static unsigned long TmpBitPlane;
41
42RegionPtr
43XAACopyPlaneColorExpansion(
44    DrawablePtr	pSrc,
45    DrawablePtr	pDst,
46    GCPtr pGC,
47    int	srcx, int srcy,
48    int	width, int height,
49    int	dstx, int dsty,
50    unsigned long bitPlane
51){
52    if((pSrc->type == DRAWABLE_PIXMAP) && !XAA_DEPTH_BUG(pGC)) {
53	if(pSrc->bitsPerPixel == 1) {
54	   return(XAABitBlt(pSrc, pDst, pGC, srcx, srcy,
55			width, height, dstx, dsty,
56			XAACopyPlane1toNColorExpand, bitPlane));
57	} else if(bitPlane < (1 << pDst->depth)){
58	   TmpBitPlane = bitPlane;
59	   return(XAABitBlt(pSrc, pDst, pGC, srcx, srcy,
60			width, height, dstx, dsty,
61			XAACopyPlaneNtoNColorExpand, bitPlane));
62	}
63    }
64
65    return (XAAFallbackOps.CopyPlane(pSrc, pDst, pGC, srcx, srcy,
66			width, height, dstx, dsty, bitPlane));
67}
68
69
70static void
71XAACopyPlane1toNColorExpand(
72    DrawablePtr   pSrc,
73    DrawablePtr	  pDst,
74    GCPtr	  pGC,
75    RegionPtr     rgnDst,
76    DDXPointPtr   pptSrc )
77{
78    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
79    BoxPtr pbox = RegionRects(rgnDst);
80    int numrects = RegionNumRects(rgnDst);
81    unsigned char *src = ((PixmapPtr)pSrc)->devPrivate.ptr;
82    int srcwidth = ((PixmapPtr)pSrc)->devKind;
83
84    while(numrects--) {
85	(*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1,
86		pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
87		src + (srcwidth * pptSrc->y) + ((pptSrc->x >> 5) << 2),
88		srcwidth, pptSrc->x & 31,
89		pGC->fgPixel, pGC->bgPixel, pGC->alu, pGC->planemask);
90	pbox++; pptSrc++;
91    }
92}
93
94
95static void
96XAACopyPlaneNtoNColorExpand(
97    DrawablePtr   pSrc,
98    DrawablePtr	  pDst,
99    GCPtr	  pGC,
100    RegionPtr     rgnDst,
101    DDXPointPtr   pptSrc
102){
103    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
104    BoxPtr pbox = RegionRects(rgnDst);
105    int numrects = RegionNumRects(rgnDst);
106    unsigned char *src = ((PixmapPtr)pSrc)->devPrivate.ptr;
107    unsigned char *data, *srcPtr, *dataPtr;
108    int srcwidth = ((PixmapPtr)pSrc)->devKind;
109    int pitch, width, height, h, i, index, offset;
110    int Bpp = pSrc->bitsPerPixel >> 3;
111    unsigned long mask = TmpBitPlane;
112
113    if(TmpBitPlane < (1 << 8)) {
114	offset = 0;
115    } else if(TmpBitPlane < (1 << 16)) {
116	offset = 1;
117	mask >>= 8;
118    } else if(TmpBitPlane < (1 << 24)) {
119	offset = 2;
120	mask >>= 16;
121    } else {
122	offset = 3;
123	mask >>= 24;
124    }
125
126    if(IS_OFFSCREEN_PIXMAP(pSrc))
127	SYNC_CHECK(pSrc);
128
129    while(numrects--) {
130	width = pbox->x2 - pbox->x1;
131	h = height = pbox->y2 - pbox->y1;
132	pitch = BitmapBytePad(width);
133
134	if(!(data = calloc(height, pitch)))
135	   goto ALLOC_FAILED;
136
137	dataPtr = data;
138        srcPtr = ((pptSrc->y) * srcwidth) + src +
139                        ((pptSrc->x) * Bpp) + offset;
140
141	while(h--) {
142	    for(i = index = 0; i < width; i++, index += Bpp) {
143	       if(mask & srcPtr[index])
144		  dataPtr[i >> 3] |= (1 << (i & 7));
145	    }
146	    dataPtr += pitch;
147	    srcPtr += srcwidth;
148	}
149
150	(*infoRec->WriteBitmap)(infoRec->pScrn,
151		pbox->x1, pbox->y1, width, height, data, pitch, 0,
152		pGC->fgPixel, pGC->bgPixel, pGC->alu, pGC->planemask);
153
154	free(data);
155
156ALLOC_FAILED:
157
158	pbox++; pptSrc++;
159    }
160}
161
162void
163XAAPushPixelsSolidColorExpansion(
164    GCPtr	pGC,
165    PixmapPtr	pBitMap,
166    DrawablePtr pDraw,
167    int	dx, int dy,
168    int xOrg, int yOrg )
169{
170   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
171   int MaxBoxes = RegionNumRects(pGC->pCompositeClip);
172   BoxPtr	pbox, pClipBoxes;
173   int		nboxes, srcx, srcy;
174   xRectangle TheRect;
175   unsigned char *src = pBitMap->devPrivate.ptr;
176   int srcwidth = pBitMap->devKind;
177
178   if(!RegionNumRects(pGC->pCompositeClip))
179	return;
180
181   TheRect.x = xOrg;
182   TheRect.y = yOrg;
183   TheRect.width = dx;
184   TheRect.height = dy;
185
186   if(MaxBoxes > (infoRec->PreAllocSize/sizeof(BoxRec))) {
187	pClipBoxes = malloc(MaxBoxes * sizeof(BoxRec));
188	if(!pClipBoxes) return;
189   } else pClipBoxes = (BoxPtr)infoRec->PreAllocMem;
190
191   nboxes = XAAGetRectClipBoxes(pGC, pClipBoxes, 1, &TheRect);
192   pbox = pClipBoxes;
193
194   while(nboxes--) {
195	srcx = pbox->x1 - xOrg;
196	srcy = pbox->y1 - yOrg;
197 	(*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1,
198		pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
199		src + (srcwidth * srcy) + ((srcx >> 5) << 2),
200		srcwidth, srcx & 31,
201		pGC->fgPixel, -1, pGC->alu, pGC->planemask);
202	pbox++;
203   }
204
205    if(pClipBoxes != (BoxPtr)infoRec->PreAllocMem)
206	free(pClipBoxes);
207}
208
209