First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / xaa / xaaImage.c
blob910c7e1e246f828d23151a3c1963b3cc59470194
2 #ifdef HAVE_XORG_CONFIG_H
3 #include <xorg-config.h>
4 #endif
6 #include "misc.h"
7 #include "xf86.h"
8 #include "xf86_OSproc.h"
9 #include "servermd.h"
11 #include <X11/X.h>
12 #include "scrnintstr.h"
13 #include "mi.h"
14 #include "pixmapstr.h"
15 #include "xf86str.h"
16 #include "xaa.h"
17 #include "xaalocal.h"
19 void XAAMoveDWORDS_FixedBase(
20 register CARD32* dest,
21 register CARD32* src,
22 register int dwords )
24 while(dwords & ~0x03) {
25 *dest = *src;
26 *dest = *(src + 1);
27 *dest = *(src + 2);
28 *dest = *(src + 3);
29 dwords -= 4;
30 src += 4;
33 if(!dwords) return;
34 *dest = *src;
35 if(dwords == 1) return;
36 *dest = *(src + 1);
37 if(dwords == 2) return;
38 *dest = *(src + 2);
41 void XAAMoveDWORDS(
42 register CARD32* dest,
43 register CARD32* src,
44 register int dwords )
46 while(dwords & ~0x03) {
47 *dest = *src;
48 *(dest + 1) = *(src + 1);
49 *(dest + 2) = *(src + 2);
50 *(dest + 3) = *(src + 3);
51 src += 4;
52 dest += 4;
53 dwords -= 4;
55 if(!dwords) return;
56 *dest = *src;
57 if(dwords == 1) return;
58 *(dest + 1) = *(src + 1);
59 if(dwords == 2) return;
60 *(dest + 2) = *(src + 2);
63 void XAAMoveDWORDS_FixedSrc(
64 register CARD32* dest,
65 register CARD32* src,
66 register int dwords )
68 while(dwords & ~0x03) {
69 *dest = *src;
70 *(dest + 1) = *src;
71 *(dest + 2) = *src;
72 *(dest + 3) = *src;
73 dest += 4;
74 dwords -= 4;
76 if(!dwords) return;
77 *dest = *src;
78 if(dwords == 1) return;
79 *(dest + 1) = *src;
80 if(dwords == 2) return;
81 *(dest + 2) = *src;
84 static void
85 XAAWritePixmap32To24(
86 ScrnInfoPtr pScrn,
87 int x, int y, int w, int h,
88 unsigned char *srcInit,
89 int srcwidth, /* bytes */
90 int rop,
91 unsigned int planemask,
92 int trans
94 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
95 int count, dwords = ((w * 3) + 3) >> 2;
96 CARD32 *src, *dst;
97 Bool PlusOne = FALSE;
99 if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) &&
100 ((dwords * h) & 0x01)) {
101 PlusOne = TRUE;
104 (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, trans, 24, 24);
105 (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, 0);
107 if(dwords > infoRec->ImageWriteRange) {
108 dst = (CARD32*)infoRec->ImageWriteBase;
109 while(h--) {
110 src = (CARD32*)srcInit;
111 count = w;
113 while(count >= 4) {
114 *dst = (src[0] & 0x00ffffff) | (src[1] << 24);
115 *dst = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
116 *dst = ((src[2] >> 16) & 0x000000ff) | (src[3] << 8);
117 src += 4;
118 count -= 4;
120 switch(count) {
121 case 0: break;
122 case 1: *dst = src[0];
123 break;
124 case 2: *dst = (src[0] & 0x00ffffff) | (src[1] << 24);
125 *dst = src[1] >> 8;
126 break;
127 default: *dst = (src[0] & 0x00ffffff) | (src[1] << 24);
128 *dst = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
129 *dst = src[2] >> 16;
130 break;
132 srcInit += srcwidth;
134 } else {
135 while(h--) {
136 dst = (CARD32*)infoRec->ImageWriteBase;
137 src = (CARD32*)srcInit;
138 count = w;
140 while(count >= 4) {
141 dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
142 dst[1] = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
143 dst[2] = ((src[2] >> 16) & 0x000000ff) | (src[3] << 8);
144 dst += 3;
145 src += 4;
146 count -= 4;
148 switch(count) {
149 case 0: break;
150 case 1: dst[0] = src[0];
151 break;
152 case 2: dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
153 dst[1] = src[1] >> 8;
154 break;
155 default: dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
156 dst[1] = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
157 dst[2] = src[2] >> 16;
158 break;
160 srcInit += srcwidth;
164 if(PlusOne) {
165 CARD32* base = (CARD32*)infoRec->ImageWriteBase;
166 *base = 0x00000000;
169 if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
170 (*infoRec->Sync)(pScrn);
171 else SET_SYNC_FLAG(infoRec);
175 void
176 XAAWritePixmap (
177 ScrnInfoPtr pScrn,
178 int x, int y, int w, int h,
179 unsigned char *src,
180 int srcwidth, /* bytes */
181 int rop,
182 unsigned int planemask,
183 int trans,
184 int bpp, int depth
186 XAAInfoRecPtr infoRec;
187 int dwords, skipleft, Bpp;
188 Bool beCareful, PlusOne;
190 if((bpp == 32) && (pScrn->bitsPerPixel == 24)) {
191 XAAWritePixmap32To24(pScrn, x, y, w, h, src, srcwidth,
192 rop, planemask, trans);
193 return;
196 infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
197 beCareful = PlusOne = FALSE;
198 Bpp = bpp >> 3;
200 if((skipleft = (long)src & 0x03L)) {
201 if(!(infoRec->ImageWriteFlags & LEFT_EDGE_CLIPPING)) {
202 skipleft = 0;
203 beCareful = TRUE;
204 goto BAD_ALIGNMENT;
207 if(Bpp == 3)
208 skipleft = 4 - skipleft;
209 else
210 skipleft /= Bpp;
212 if((x < skipleft) && !(infoRec->ImageWriteFlags &
213 LEFT_EDGE_CLIPPING_NEGATIVE_X)) {
214 skipleft = 0;
215 beCareful = TRUE;
216 goto BAD_ALIGNMENT;
219 x -= skipleft;
220 w += skipleft;
222 if(Bpp == 3)
223 src -= 3 * skipleft;
224 else /* is this Alpha friendly ? */
225 src = (unsigned char*)((long)src & ~0x03L);
228 BAD_ALIGNMENT:
230 dwords = ((w * Bpp) + 3) >> 2;
232 if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) &&
233 ((dwords * h) & 0x01)) {
234 PlusOne = TRUE;
238 (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, trans, bpp, depth);
239 (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, skipleft);
241 if(beCareful) {
242 /* in cases with bad alignment we have to be careful not
243 to read beyond the end of the source */
244 if(((x * Bpp) + (dwords << 2)) > srcwidth) h--;
245 else beCareful = FALSE;
248 if(dwords > infoRec->ImageWriteRange) {
249 while(h--) {
250 XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase,
251 (CARD32*)src, dwords);
252 src += srcwidth;
254 if(beCareful) {
255 int shift = ((long)src & 0x03L) << 3;
256 if(--dwords)
257 XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase,
258 (CARD32*)src, dwords);
259 src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
260 *((CARD32*)infoRec->ImageWriteBase) = *((CARD32*)src) >> shift;
262 } else {
263 if(srcwidth == (dwords << 2)) {
264 int decrement = infoRec->ImageWriteRange/dwords;
266 while(h > decrement) {
267 XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
268 (CARD32*)src, dwords * decrement);
269 src += (srcwidth * decrement);
270 h -= decrement;
272 if(h) {
273 XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
274 (CARD32*)src, dwords * h);
275 if(beCareful) src += (srcwidth * h);
277 } else {
278 while(h--) {
279 XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
280 (CARD32*)src, dwords);
281 src += srcwidth;
285 if(beCareful) {
286 int shift = ((long)src & 0x03L) << 3;
287 if(--dwords)
288 XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
289 (CARD32*)src, dwords);
290 src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
292 ((CARD32*)infoRec->ImageWriteBase)[dwords] =
293 *((CARD32*)src) >> shift;
297 if(PlusOne) {
298 CARD32* base = (CARD32*)infoRec->ImageWriteBase;
299 *base = 0x00000000;
302 if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
303 (*infoRec->Sync)(pScrn);
304 else SET_SYNC_FLAG(infoRec);
308 void
309 XAAWritePixmapScanline (
310 ScrnInfoPtr pScrn,
311 int x, int y, int w, int h,
312 unsigned char *src,
313 int srcwidth, /* bytes */
314 int rop,
315 unsigned int planemask,
316 int trans,
317 int bpp, int depth
319 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
320 int dwords, skipleft, bufferNo = 0, Bpp = bpp >> 3;
321 Bool beCareful = FALSE;
322 CARD32* base;
324 if((skipleft = (long)src & 0x03L)) {
325 if(!(infoRec->ScanlineImageWriteFlags & LEFT_EDGE_CLIPPING)) {
326 skipleft = 0;
327 beCareful = TRUE;
328 goto BAD_ALIGNMENT;
331 if(Bpp == 3)
332 skipleft = 4 - skipleft;
333 else
334 skipleft /= Bpp;
336 if((x < skipleft) && !(infoRec->ScanlineImageWriteFlags &
337 LEFT_EDGE_CLIPPING_NEGATIVE_X)) {
338 skipleft = 0;
339 beCareful = TRUE;
340 goto BAD_ALIGNMENT;
343 x -= skipleft;
344 w += skipleft;
346 if(Bpp == 3)
347 src -= 3 * skipleft;
348 else
349 src = (unsigned char*)((long)src & ~0x03L);
352 BAD_ALIGNMENT:
354 dwords = ((w * Bpp) + 3) >> 2;
356 (*infoRec->SetupForScanlineImageWrite)(
357 pScrn, rop, planemask, trans, bpp, depth);
358 (*infoRec->SubsequentScanlineImageWriteRect)(pScrn, x, y, w, h, skipleft);
360 if(beCareful) {
361 /* in cases with bad alignment we have to be careful not
362 to read beyond the end of the source */
363 if(((x * Bpp) + (dwords << 2)) > srcwidth) h--;
364 else beCareful = FALSE;
367 while(h--) {
368 base = (CARD32*)infoRec->ScanlineImageWriteBuffers[bufferNo];
369 XAAMoveDWORDS(base, (CARD32*)src, dwords);
370 (*infoRec->SubsequentImageWriteScanline)(pScrn, bufferNo++);
371 src += srcwidth;
372 if(bufferNo >= infoRec->NumScanlineImageWriteBuffers)
373 bufferNo = 0;
376 if(beCareful) {
377 int shift = ((long)src & 0x03L) << 3;
378 base = (CARD32*)infoRec->ScanlineImageWriteBuffers[bufferNo];
379 if(--dwords)
380 XAAMoveDWORDS(base,(CARD32*)src, dwords);
381 src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
383 base[dwords] = *((CARD32*)src) >> shift;
384 (*infoRec->SubsequentImageWriteScanline)(pScrn, bufferNo);
387 SET_SYNC_FLAG(infoRec);
391 void
392 XAAPutImage(
393 DrawablePtr pDraw,
394 GCPtr pGC,
395 int depth,
396 int x,
397 int y,
398 int w,
399 int h,
400 int leftPad,
401 int format,
402 char *pImage
404 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
405 int bpp = BitsPerPixel(depth);
406 Bool depthBug = FALSE;
407 if(!w || !h) return;
409 if(!REGION_NUM_RECTS(pGC->pCompositeClip))
410 return;
412 depthBug = XAA_DEPTH_BUG(pGC);
414 if(((format == ZPixmap) && infoRec->WritePixmap &&
415 ((pDraw->bitsPerPixel == bpp) ||
416 ((pDraw->bitsPerPixel == 24) && (bpp == 32) &&
417 (infoRec->WritePixmapFlags & CONVERT_32BPP_TO_24BPP))) &&
418 CHECK_ROP(pGC,infoRec->WritePixmapFlags) &&
419 CHECK_ROPSRC(pGC,infoRec->WritePixmapFlags) &&
420 CHECK_PLANEMASK(pGC,infoRec->WritePixmapFlags) &&
421 CHECK_NO_GXCOPY(pGC,infoRec->WritePixmapFlags)) ||
422 ((format == XYBitmap) && !depthBug && infoRec->WriteBitmap &&
423 CHECK_ROP(pGC,infoRec->WriteBitmapFlags) &&
424 CHECK_ROPSRC(pGC,infoRec->WriteBitmapFlags) &&
425 CHECK_PLANEMASK(pGC,infoRec->WriteBitmapFlags) &&
426 CHECK_COLORS(pGC,infoRec->WriteBitmapFlags) &&
427 !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY)) ||
428 ((format == XYPixmap) && !depthBug && infoRec->WriteBitmap &&
429 CHECK_ROP(pGC,infoRec->WriteBitmapFlags) &&
430 CHECK_ROPSRC(pGC,infoRec->WriteBitmapFlags) &&
431 !(infoRec->WriteBitmapFlags & NO_PLANEMASK) &&
432 !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY))){
434 int MaxBoxes = REGION_NUM_RECTS(pGC->pCompositeClip);
435 BoxPtr pbox, pClipBoxes;
436 int nboxes, srcx, srcy, srcwidth;
437 xRectangle TheRect;
439 TheRect.x = pDraw->x + x;
440 TheRect.y = pDraw->y + y;
441 TheRect.width = w;
442 TheRect.height = h;
444 if(MaxBoxes > (infoRec->PreAllocSize/sizeof(BoxRec))) {
445 pClipBoxes = xalloc(MaxBoxes * sizeof(BoxRec));
446 if(!pClipBoxes) return;
447 } else pClipBoxes = (BoxPtr)infoRec->PreAllocMem;
449 nboxes = XAAGetRectClipBoxes(pGC, pClipBoxes, 1, &TheRect);
450 pbox = pClipBoxes;
452 if(format == XYBitmap) {
453 srcwidth = BitmapBytePad(leftPad + w);
454 while(nboxes--) {
455 srcx = pbox->x1 - TheRect.x + leftPad;
456 srcy = pbox->y1 - TheRect.y;
457 (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1,
458 pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
459 (unsigned char*)pImage +
460 (srcwidth * srcy) + ((srcx >> 5) << 2),
461 srcwidth, srcx & 31, pGC->fgPixel, pGC->bgPixel,
462 pGC->alu, pGC->planemask);
463 pbox++;
465 } else if(format == ZPixmap) {
466 int Bpp = bpp >> 3;
467 srcwidth = PixmapBytePad(leftPad + w, depth);
468 while(nboxes--) {
469 srcx = pbox->x1 - TheRect.x + leftPad;
470 srcy = pbox->y1 - TheRect.y;
471 (*infoRec->WritePixmap)(infoRec->pScrn, pbox->x1, pbox->y1,
472 pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
473 (unsigned char*)pImage +
474 (srcwidth * srcy) + (srcx * Bpp),
475 srcwidth, pGC->alu, pGC->planemask, -1,
476 Bpp << 3, depth);
477 pbox++;
479 } else { /* XYPixmap */
480 int depth = pGC->depth;
481 int numBox, increment;
482 unsigned long i, mask;
483 BoxPtr pntBox;
485 srcwidth = BitmapBytePad(w + leftPad);
486 increment = h * srcwidth;
487 i = 1 << (depth - 1);
488 mask = ~0;
490 if((infoRec->pScrn->overlayFlags & OVERLAY_8_32_PLANAR) &&
491 (pGC->depth == 8)){
492 i = 0x80000000; mask = 0xff000000;
495 for(; i & mask; i >>= 1, pImage += increment) {
496 if(i & pGC->planemask) {
497 pntBox = pbox;
498 numBox = nboxes;
499 while(numBox--) {
500 srcx = pntBox->x1 - TheRect.x + leftPad;
501 srcy = pntBox->y1 - TheRect.y;
502 (*infoRec->WriteBitmap)(infoRec->pScrn,
503 pntBox->x1, pntBox->y1,
504 pntBox->x2 - pntBox->x1,
505 pntBox->y2 - pntBox->y1,
506 (unsigned char*)pImage +
507 (srcwidth * srcy) + ((srcx >> 5) << 2),
508 srcwidth, srcx & 31, ~0, 0, pGC->alu, i);
509 pntBox++;
516 if(pClipBoxes != (BoxPtr)infoRec->PreAllocMem)
517 xfree(pClipBoxes);
518 } else
519 XAAFallbackOps.PutImage(pDraw, pGC, depth, x, y, w, h, leftPad,
520 format, pImage);