First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / xf8_32bpp / cfbcpyarea.c
blobc2eb1a04e20b6405b3ac4a5c06a777ea58752a03
2 #ifdef HAVE_XORG_CONFIG_H
3 #include <xorg-config.h>
4 #endif
6 #include <stdlib.h>
8 #include <X11/X.h>
9 #include <X11/Xmd.h>
10 #include "servermd.h"
11 #include "scrnintstr.h"
12 #include "pixmapstr.h"
13 #include "resource.h"
14 #include "colormap.h"
15 #include "colormapst.h"
16 #define PSZ 8
17 #include "cfb.h"
18 #undef PSZ
19 #include "cfb32.h"
20 #include "cfb8_32.h"
21 #include "mi.h"
22 #include "mistruct.h"
23 #include "dix.h"
24 #include "mibstore.h"
27 RegionPtr
28 cfb8_32CopyArea(
29 DrawablePtr pSrcDraw,
30 DrawablePtr pDstDraw,
31 GC *pGC,
32 int srcx, int srcy,
33 int width, int height,
34 int dstx, int dsty
37 if(pSrcDraw->bitsPerPixel == 32) {
38 if(pDstDraw->bitsPerPixel == 32) {
39 if((pGC->alu == GXcopy) && (pGC->planemask == 0xff000000)) {
40 return cfb32BitBlt (pSrcDraw, pDstDraw,
41 pGC, srcx, srcy, width, height, dstx, dsty,
42 cfbDoBitblt8To8GXcopy, 0L);
44 return(cfb32CopyArea(pSrcDraw, pDstDraw, pGC, srcx, srcy,
45 width, height, dstx, dsty));
46 } else {
47 /* have to translate 32 -> 8 copies */
48 return cfb32BitBlt (pSrcDraw, pDstDraw,
49 pGC, srcx, srcy, width, height, dstx, dsty,
50 cfbDoBitblt32To8, 0L);
52 } else {
53 if(pDstDraw->bitsPerPixel == 32) {
54 /* have to translate 8 -> 32 copies */
55 return cfb32BitBlt (pSrcDraw, pDstDraw,
56 pGC, srcx, srcy, width, height, dstx, dsty,
57 cfbDoBitblt8To32, 0L);
58 } else {
59 return(cfbCopyArea(pSrcDraw, pDstDraw, pGC, srcx, srcy,
60 width, height, dstx, dsty));
68 void
69 cfbDoBitblt8To32(
70 DrawablePtr pSrc,
71 DrawablePtr pDst,
72 int rop,
73 RegionPtr prgnDst,
74 DDXPointPtr pptSrc,
75 unsigned long pm
77 BoxPtr pbox = REGION_RECTS(prgnDst);
78 int nbox = REGION_NUM_RECTS(prgnDst);
79 unsigned char *ptr8, *ptr32;
80 unsigned char *data8, *data32;
81 int pitch8, pitch32;
82 int height, width, i;
84 cfbGetByteWidthAndPointer(pSrc, pitch8, ptr8);
85 cfbGetByteWidthAndPointer(pDst, pitch32, ptr32);
86 ptr32 += 3; /* point to the top byte */
88 pm >>= 24;
90 if((pm == 0xff) && (rop == GXcopy)) {
91 for(;nbox; pbox++, pptSrc++, nbox--) {
92 data8 = ptr8 + (pptSrc->y * pitch8) + pptSrc->x;
93 data32 = ptr32 + (pbox->y1 * pitch32) + (pbox->x1 << 2);
94 width = pbox->x2 - pbox->x1;
95 height = pbox->y2 - pbox->y1;
97 while(height--) {
98 for(i = 0; i < width; i++)
99 data32[i << 2] = data8[i];
100 data8 += pitch8;
101 data32 += pitch32;
104 } else { /* it ain't pretty, but hey */
105 for(;nbox; pbox++, pptSrc++, nbox--) {
106 data8 = ptr8 + (pptSrc->y * pitch8) + pptSrc->x;
107 data32 = ptr32 + (pbox->y1 * pitch32) + (pbox->x1 << 2);
108 width = pbox->x2 - pbox->x1;
109 height = pbox->y2 - pbox->y1;
111 while(height--) {
112 switch(rop) {
113 case GXcopy:
114 for(i = 0; i < width; i++)
115 data32[i<<2] = (data8[i] & pm) | (data32[i<<2] & ~pm);
116 break;
117 case GXor:
118 for(i = 0; i < width; i++)
119 data32[i<<2] |= data8[i] & pm;
120 break;
121 case GXclear:
122 for(i = 0; i < width; i++)
123 data32[i<<2] &= ~pm;
124 break;
125 case GXand:
126 for(i = 0; i < width; i++)
127 data32[i<<2] &= data8[i] | ~pm;
128 break;
129 case GXandReverse:
130 for(i = 0; i < width; i++)
131 data32[i<<2] = ~data32[i<<2] & (data8[i] | ~pm);
132 break;
133 case GXandInverted:
134 for(i = 0; i < width; i++)
135 data32[i<<2] &= ~data8[i] | ~pm;
136 break;
137 case GXnoop:
138 return;
139 case GXxor:
140 for(i = 0; i < width; i++)
141 data32[i<<2] ^= data8[i] & pm;
142 break;
143 case GXnor:
144 for(i = 0; i < width; i++)
145 data32[i<<2] = ~(data32[i<<2] | (data8[i] & pm));
146 break;
147 case GXequiv:
148 for(i = 0; i < width; i++)
149 data32[i<<2] = ~(data32[i<<2] ^ (data8[i] & pm));
150 break;
151 case GXinvert:
152 for(i = 0; i < width; i++)
153 data32[i<<2] ^= pm;
154 break;
155 case GXorReverse:
156 for(i = 0; i < width; i++)
157 data32[i<<2] = ~data32[i<<2] | (data8[i] & pm);
158 break;
159 case GXcopyInverted:
160 for(i = 0; i < width; i++)
161 data32[i<<2] = (~data8[i] & pm) | (data32[i<<2] & ~pm);
162 break;
163 case GXorInverted:
164 for(i = 0; i < width; i++)
165 data32[i<<2] |= ~data8[i] & pm;
166 break;
167 case GXnand:
168 for(i = 0; i < width; i++)
169 data32[i<<2] = ~(data32[i<<2] & (data8[i] | ~pm));
170 break;
171 case GXset:
172 for(i = 0; i < width; i++)
173 data32[i<<2] |= pm;
174 break;
176 data8 += pitch8;
177 data32 += pitch32;
184 void
185 cfbDoBitblt32To8(
186 DrawablePtr pSrc,
187 DrawablePtr pDst,
188 int rop,
189 RegionPtr prgnDst,
190 DDXPointPtr pptSrc,
191 unsigned long pm
193 BoxPtr pbox = REGION_RECTS(prgnDst);
194 int nbox = REGION_NUM_RECTS(prgnDst);
195 unsigned char *ptr8, *ptr32;
196 unsigned char *data8, *data32;
197 int pitch8, pitch32;
198 int height, width, i;
200 cfbGetByteWidthAndPointer(pDst, pitch8, ptr8);
201 cfbGetByteWidthAndPointer(pSrc, pitch32, ptr32);
202 ptr32 += 3; /* point to the top byte */
204 if(((pm & 0xff) == 0xff) && (rop == GXcopy)) {
205 for(;nbox; pbox++, pptSrc++, nbox--) {
206 data8 = ptr8 + (pbox->y1 * pitch8) + pbox->x1;
207 data32 = ptr32 + (pptSrc->y * pitch32) + (pptSrc->x << 2);
209 width = pbox->x2 - pbox->x1;
210 height = pbox->y2 - pbox->y1;
212 while(height--) {
213 for(i = 0; i < width; i++)
214 data8[i] = data32[i << 2];
215 data8 += pitch8;
216 data32 += pitch32;
219 } else {
220 for(;nbox; pbox++, pptSrc++, nbox--) {
221 data8 = ptr8 + (pbox->y1 * pitch8) + pbox->x1;
222 data32 = ptr32 + (pptSrc->y * pitch32) + (pptSrc->x << 2);
224 width = pbox->x2 - pbox->x1;
225 height = pbox->y2 - pbox->y1;
227 while(height--) {
228 switch(rop) {
229 case GXcopy:
230 for(i = 0; i < width; i++)
231 data8[i] = (data32[i<<2] & pm) | (data8[i] & ~pm);
232 break;
233 case GXor:
234 for(i = 0; i < width; i++)
235 data8[i] |= data32[i<<2] & pm;
236 break;
237 case GXclear:
238 for(i = 0; i < width; i++)
239 data8[i] &= ~pm;
240 break;
241 case GXand:
242 for(i = 0; i < width; i++)
243 data8[i] &= data32[i<<2] | ~pm;
244 break;
245 case GXandReverse:
246 for(i = 0; i < width; i++)
247 data8[i] = ~data8[i] & (data32[i<<2] | ~pm);
248 break;
249 case GXandInverted:
250 for(i = 0; i < width; i++)
251 data8[i] &= ~data32[i<<2] | ~pm;
252 break;
253 case GXnoop:
254 return;
255 case GXxor:
256 for(i = 0; i < width; i++)
257 data8[i] ^= data32[i<<2] & pm;
258 break;
259 case GXnor:
260 for(i = 0; i < width; i++)
261 data8[i] = ~(data8[i] | (data32[i<<2] & pm));
262 break;
263 case GXequiv:
264 for(i = 0; i < width; i++)
265 data8[i] = ~(data8[i] ^ (data32[i<<2] & pm));
266 break;
267 case GXinvert:
268 for(i = 0; i < width; i++)
269 data8[i] ^= pm;
270 break;
271 case GXorReverse:
272 for(i = 0; i < width; i++)
273 data8[i] = ~data8[i] | (data32[i<<2] & pm);
274 break;
275 case GXcopyInverted:
276 for(i = 0; i < width; i++)
277 data8[i] = (~data32[i<<2] & pm) | (data8[i] & ~pm);
278 break;
279 case GXorInverted:
280 for(i = 0; i < width; i++)
281 data8[i] |= ~data32[i<<2] & pm;
282 break;
283 case GXnand:
284 for(i = 0; i < width; i++)
285 data8[i] = ~(data8[i] & (data32[i<<2] | ~pm));
286 break;
287 case GXset:
288 for(i = 0; i < width; i++)
289 data8[i] |= pm;
290 break;
292 data8 += pitch8;
293 data32 += pitch32;
301 static void
302 Do8To8Blt(
303 unsigned char *SrcPtr,
304 int SrcPitch,
305 unsigned char *DstPtr,
306 int DstPitch,
307 int nbox,
308 DDXPointPtr pptSrc,
309 BoxPtr pbox,
310 int xdir, int ydir
312 int i, j, width, height, ydir2;
313 CARD8 *src, *dst;
315 SrcPtr += 3;
316 DstPtr += 3;
317 xdir *= 4;
318 ydir2 = ydir * DstPitch;
319 ydir *= SrcPitch;
321 for(;nbox; pbox++, pptSrc++, nbox--) {
322 src = SrcPtr + (pptSrc->y * SrcPitch) + (pptSrc->x << 2);
323 dst = DstPtr + (pbox->y1 * DstPitch) + (pbox->x1 << 2);
324 width = pbox->x2 - pbox->x1;
325 height = pbox->y2 - pbox->y1;
327 if(ydir < 0) {
328 src += (height - 1) * SrcPitch;
329 dst += (height - 1) * DstPitch;
332 if(xdir < 0) {
333 register int tmp = (width - 1) << 2;
334 src += tmp;
335 dst += tmp;
338 while(height--) {
339 for(i = width, j = 0; i--; j+=xdir)
340 dst[j] = src[j];
341 src += ydir;
342 dst += ydir2;
347 static void
348 Do24To24Blt(
349 unsigned char *SrcPtr,
350 int SrcPitch,
351 unsigned char *DstPtr,
352 int DstPitch,
353 int nbox,
354 DDXPointPtr pptSrc,
355 BoxPtr pbox,
356 int xdir, int ydir
358 int i, j, width, height, ydir2;
359 CARD8 *src, *dst;
361 xdir *= 4;
362 ydir2 = ydir * DstPitch;
363 ydir *= SrcPitch;
365 for(;nbox; pbox++, pptSrc++, nbox--) {
366 src = SrcPtr + (pptSrc->y * SrcPitch) + (pptSrc->x << 2);
367 dst = DstPtr + (pbox->y1 * DstPitch) + (pbox->x1 << 2);
368 width = pbox->x2 - pbox->x1;
369 height = pbox->y2 - pbox->y1;
371 if(ydir < 0) {
372 src += (height - 1) * SrcPitch;
373 dst += (height - 1) * DstPitch;
376 if(xdir < 0) {
377 register int tmp = (width - 1) << 2;
378 src += tmp;
379 dst += tmp;
382 while(height--) {
383 for(i = width, j = 0; i--; j+=xdir) {
384 *((CARD16*)(dst + j)) = *((CARD32*)(src + j));
385 dst[j + 2] = src[j + 2];
387 src += ydir;
388 dst += ydir2;
394 static void
395 cfb8_32DoBitBlt(
396 DrawablePtr pSrc,
397 DrawablePtr pDst,
398 RegionPtr prgnDst,
399 DDXPointPtr pptSrc,
400 void (*DoBlt)(
401 unsigned char *SrcPtr,
402 int SrcPitch,
403 unsigned char *DstPtr,
404 int DstPitch,
405 int nbox,
406 DDXPointPtr pptSrc,
407 BoxPtr pbox,
408 int xdir, int ydir)
410 int nbox, careful, SrcPitch, DstPitch;
411 BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
412 DDXPointPtr pptTmp, pptNew1, pptNew2;
413 int xdir, ydir;
414 unsigned char *SrcPtr, *DstPtr;
416 /* XXX we have to err on the side of safety when both are windows,
417 * because we don't know if IncludeInferiors is being used.
419 careful = ((pSrc == pDst) ||
420 ((pSrc->type == DRAWABLE_WINDOW) &&
421 (pDst->type == DRAWABLE_WINDOW)));
423 pbox = REGION_RECTS(prgnDst);
424 nbox = REGION_NUM_RECTS(prgnDst);
426 pboxNew1 = NULL;
427 pptNew1 = NULL;
428 pboxNew2 = NULL;
429 pptNew2 = NULL;
430 if (careful && (pptSrc->y < pbox->y1)) {
431 /* walk source botttom to top */
432 ydir = -1;
434 if (nbox > 1) {
435 /* keep ordering in each band, reverse order of bands */
436 pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
437 if(!pboxNew1)
438 return;
439 pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
440 if(!pptNew1) {
441 DEALLOCATE_LOCAL(pboxNew1);
442 return;
444 pboxBase = pboxNext = pbox+nbox-1;
445 while (pboxBase >= pbox) {
446 while ((pboxNext >= pbox) &&
447 (pboxBase->y1 == pboxNext->y1))
448 pboxNext--;
449 pboxTmp = pboxNext+1;
450 pptTmp = pptSrc + (pboxTmp - pbox);
451 while (pboxTmp <= pboxBase) {
452 *pboxNew1++ = *pboxTmp++;
453 *pptNew1++ = *pptTmp++;
455 pboxBase = pboxNext;
457 pboxNew1 -= nbox;
458 pbox = pboxNew1;
459 pptNew1 -= nbox;
460 pptSrc = pptNew1;
462 } else {
463 /* walk source top to bottom */
464 ydir = 1;
467 if (careful && (pptSrc->x < pbox->x1)) {
468 /* walk source right to left */
469 xdir = -1;
471 if (nbox > 1) {
472 /* reverse order of rects in each band */
473 pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
474 pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
475 if(!pboxNew2 || !pptNew2) {
476 if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
477 if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
478 if (pboxNew1) {
479 DEALLOCATE_LOCAL(pptNew1);
480 DEALLOCATE_LOCAL(pboxNew1);
482 return;
484 pboxBase = pboxNext = pbox;
485 while (pboxBase < pbox+nbox) {
486 while ((pboxNext < pbox+nbox) &&
487 (pboxNext->y1 == pboxBase->y1))
488 pboxNext++;
489 pboxTmp = pboxNext;
490 pptTmp = pptSrc + (pboxTmp - pbox);
491 while (pboxTmp != pboxBase) {
492 *pboxNew2++ = *--pboxTmp;
493 *pptNew2++ = *--pptTmp;
495 pboxBase = pboxNext;
497 pboxNew2 -= nbox;
498 pbox = pboxNew2;
499 pptNew2 -= nbox;
500 pptSrc = pptNew2;
502 } else {
503 /* walk source left to right */
504 xdir = 1;
507 cfbGetByteWidthAndPointer(pSrc, SrcPitch, SrcPtr);
508 cfbGetByteWidthAndPointer(pDst, DstPitch, DstPtr);
510 (*DoBlt)(SrcPtr,SrcPitch,DstPtr,DstPitch,nbox,pptSrc,pbox,xdir,ydir);
512 if (pboxNew2) {
513 DEALLOCATE_LOCAL(pptNew2);
514 DEALLOCATE_LOCAL(pboxNew2);
516 if (pboxNew1) {
517 DEALLOCATE_LOCAL(pptNew1);
518 DEALLOCATE_LOCAL(pboxNew1);
524 /* A couple routines to speed up full planemask copies */
526 void
527 cfbDoBitblt8To8GXcopy(
528 DrawablePtr pSrc,
529 DrawablePtr pDst,
530 int rop,
531 RegionPtr prgnDst,
532 DDXPointPtr pptSrc,
533 unsigned long pm
535 cfb8_32DoBitBlt(pSrc, pDst, prgnDst, pptSrc, Do8To8Blt);
539 void
540 cfbDoBitblt24To24GXcopy(
541 DrawablePtr pSrc,
542 DrawablePtr pDst,
543 int rop,
544 RegionPtr prgnDst,
545 DDXPointPtr pptSrc,
546 unsigned long pm
548 cfb8_32DoBitBlt(pSrc, pDst, prgnDst, pptSrc, Do24To24Blt);