initial commit
[profile/ivi/xorg-x11-server.git] / hw / xfree86 / xaa / xaaBitmap.c
1
2
3 #ifdef HAVE_XORG_CONFIG_H
4 #include <xorg-config.h>
5 #endif
6
7 #include "xaa.h"
8 #include "xaalocal.h"
9 #include "xaacexp.h"
10 #include "xf86.h"
11
12
13 /********** byte swapping ***************/
14
15
16 #ifdef FIXEDBASE
17 # define DEST(i)        *dest
18 # define RETURN(i)      return(dest)
19 #else
20 # define DEST(i)        dest[i]
21 # define RETURN(i)      return(dest + i)
22 #endif
23
24 #ifdef MSBFIRST
25 # define SOURCE(i)      SWAP_BITS_IN_BYTES(src[i])
26 #else
27 # define SOURCE(i)      src[i]
28 #endif
29
30
31 typedef CARD32 *(* BitmapScanlineProcPtr)(CARD32 *, CARD32 *, int, int);
32
33 #ifdef TRIPLE_BITS
34 static CARD32*
35 BitmapScanline(
36    CARD32 *src, CARD32 *base,
37    int count, int skipleft )
38 {
39      CARD32 bits;
40
41      while(count >= 3) {
42         bits = *src;
43         WRITE_BITS3(bits);
44         src++;
45         count -= 3;
46      }
47      if (count == 2) {
48         bits = *src;
49         WRITE_BITS2(bits);
50      } else if (count == 1) {
51         bits = *src;
52         WRITE_BITS1(bits);
53      }
54      
55      return base;
56 }
57
58 static CARD32*
59 BitmapScanline_Inverted(
60    CARD32 *src, CARD32 *base,
61    int count, int skipleft )
62 {
63      CARD32 bits;
64
65      while(count >= 3) {
66         bits = ~(*src);
67         WRITE_BITS3(bits);
68         src++;
69         count -= 3;
70      }
71      if (count == 2) {
72         bits = ~(*src);
73         WRITE_BITS2(bits);
74      } else if (count == 1) {
75         bits = ~(*src);
76         WRITE_BITS1(bits);
77      }
78      
79      return base;
80 }
81
82
83 static CARD32*
84 BitmapScanline_Shifted(
85    CARD32 *src, CARD32 *base,
86    int count, int skipleft )
87 {
88      CARD32 bits;
89
90      while(count >= 3) {
91         bits = SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft));
92         WRITE_BITS3(bits);
93         src++;
94         count -= 3;
95      }
96      if (count == 2) {
97         bits = SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft));
98         WRITE_BITS2(bits);
99      } else if (count == 1) {
100         bits = SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft));
101         WRITE_BITS1(bits);
102      }
103      
104      return base;
105 }
106
107 static CARD32*
108 BitmapScanline_Shifted_Inverted(
109    CARD32 *src, CARD32 *base,
110    int count, int skipleft )
111 {
112      CARD32 bits;
113
114      while(count >= 3) {
115         bits = ~(SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft)));
116         WRITE_BITS3(bits);
117         src++;
118         count -= 3;
119      }
120      if (count == 2) {
121         bits = ~(SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft)));
122         WRITE_BITS2(bits);
123      } else if (count == 1) {
124         bits = ~(SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft)));
125         WRITE_BITS1(bits);
126      }
127      
128      return base;
129 }
130
131 #define BitmapScanline_Shifted_Careful BitmapScanline_Shifted
132 #define BitmapScanline_Shifted_Inverted_Careful BitmapScanline_Shifted_Inverted
133
134 #else
135 static CARD32*
136 BitmapScanline(
137    CARD32 *src, CARD32 *dest,
138    int count, int skipleft )
139 {
140    while(count >= 4) {
141         DEST(0) = SOURCE(0);
142         DEST(1) = SOURCE(1);
143         DEST(2) = SOURCE(2);
144         DEST(3) = SOURCE(3);
145         count -= 4;
146         src += 4;
147 #ifndef FIXEDBASE
148         dest += 4;
149 #endif
150    }
151    
152    if(!count) return dest;
153    DEST(0) = SOURCE(0);
154    if(count == 1) RETURN(1);
155    DEST(1) = SOURCE(1);
156    if(count == 2) RETURN(2);
157    DEST(2) = SOURCE(2);
158    RETURN(3);
159 }
160
161 static CARD32*
162 BitmapScanline_Inverted(
163    CARD32 *src, CARD32 *dest,
164    int count, int skipleft )
165 {
166    while(count >= 4) {
167         DEST(0) = ~SOURCE(0);
168         DEST(1) = ~SOURCE(1);
169         DEST(2) = ~SOURCE(2);
170         DEST(3) = ~SOURCE(3);
171         count -= 4;
172         src += 4;
173 #ifndef FIXEDBASE
174         dest += 4;
175 #endif
176    }
177    
178    if(!count) return dest;
179    DEST(0) = ~SOURCE(0);
180    if(count == 1) RETURN(1);
181    DEST(1) = ~SOURCE(1);
182    if(count == 2) RETURN(2);
183    DEST(2) = ~SOURCE(2);
184    RETURN(3);
185 }
186
187
188 static CARD32*
189 BitmapScanline_Shifted(
190    CARD32 *bits, CARD32 *base,
191    int count, int skipleft )
192 {
193      while(count--) {
194         register CARD32 tmp = SHIFT_R(*bits,skipleft) | 
195                               SHIFT_L(*(bits + 1),(32 - skipleft));
196         WRITE_BITS(tmp);
197         bits++;
198      }
199      return base;
200 }
201
202 static CARD32*
203 BitmapScanline_Shifted_Inverted(
204    CARD32 *bits, CARD32 *base,
205    int count, int skipleft )
206 {
207      while(count--) {
208         register CARD32 tmp = ~(SHIFT_R(*bits,skipleft) | 
209                                 SHIFT_L(*(bits + 1),(32 - skipleft)));
210         WRITE_BITS(tmp);
211         bits++;
212      }
213      return base;
214 }
215
216 static CARD32*
217 BitmapScanline_Shifted_Careful(
218    CARD32 *bits, CARD32 *base,
219    int count, int skipleft )
220 {
221      register CARD32 tmp;
222      while(--count) {
223         tmp = SHIFT_R(*bits,skipleft) | SHIFT_L(*(bits + 1),(32 - skipleft));
224         WRITE_BITS(tmp);
225         bits++;
226      }
227      tmp = SHIFT_R(*bits,skipleft);
228      WRITE_BITS(tmp);
229
230      return base;
231 }
232
233 static CARD32*
234 BitmapScanline_Shifted_Inverted_Careful(
235    CARD32 *bits, CARD32 *base,
236    int count, int skipleft )
237 {
238      register CARD32 tmp;
239      while(--count) {
240         tmp = ~(SHIFT_R(*bits,skipleft) | SHIFT_L(*(bits + 1),(32 - skipleft)));
241         WRITE_BITS(tmp);
242         bits++;
243      }
244      tmp = ~(SHIFT_R(*bits,skipleft));
245      WRITE_BITS(tmp);
246      return base;
247 }
248
249 #endif
250
251 /*  
252     When the accelerator is TRANSPARENCY_ONLY, WriteBitmap can do
253     the fill in two passes, inverting the source on the second pass.  
254     For GXcopy we can fill the backing rectangle as a solid rect and
255     avoid the invert.
256 */ 
257
258 void
259 #ifdef TRIPLE_BITS
260 EXPNAME(XAAWriteBitmapColorExpand3)(
261 #else
262 EXPNAME(XAAWriteBitmapColorExpand)(
263 #endif
264     ScrnInfoPtr pScrn,
265     int x, int y, int w, int H,
266     unsigned char *src,
267     int srcwidth,
268     int skipleft,
269     int fg, int bg,
270     int rop,
271     unsigned int planemask 
272 )
273 {
274     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
275     CARD32* base;
276     unsigned char *srcp = src;
277     int SecondPassColor = -1;
278     int shift = 0, dwords;
279     BitmapScanlineProcPtr firstFunc;
280     BitmapScanlineProcPtr secondFunc;
281     int flag;
282     int h = H;
283
284 #ifdef TRIPLE_BITS
285     if((bg != -1) && 
286         ((infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) ||
287         ((infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) && 
288         (!CHECK_RGB_EQUAL(bg))))) {
289 #else
290     if((bg != -1) && 
291         (infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
292 #endif
293         if((rop == GXcopy) && infoRec->SetupForSolidFill) {
294             (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
295             (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
296         } else SecondPassColor = bg;
297         bg = -1;
298     }
299
300 #ifdef TRIPLE_BITS
301     if(skipleft) {
302 #else
303     if(skipleft && 
304         (!(infoRec->CPUToScreenColorExpandFillFlags & LEFT_EDGE_CLIPPING) || 
305         (!(infoRec->CPUToScreenColorExpandFillFlags & LEFT_EDGE_CLIPPING_NEGATIVE_X) && 
306                 (skipleft > x)))) {
307 #endif
308         if((skipleft + ((w + 31) & ~31)) > ((skipleft + w + 31) & ~31)) {
309             /* don't read past the end */
310             firstFunc = BitmapScanline_Shifted_Careful;
311             secondFunc = BitmapScanline_Shifted_Inverted_Careful;
312         } else {
313             firstFunc = BitmapScanline_Shifted;
314             secondFunc = BitmapScanline_Shifted_Inverted;
315         }
316         shift = skipleft;
317         skipleft = 0;
318     } else {
319         firstFunc = BitmapScanline;
320         secondFunc = BitmapScanline_Inverted;
321         w += skipleft;
322         x -= skipleft;
323     }
324
325 #ifdef TRIPLE_BITS
326     dwords = (3 * w + 31) >> 5;
327 #else
328     dwords = (w + 31) >> 5;
329 #endif
330
331 SECOND_PASS:
332
333     flag = (infoRec->CPUToScreenColorExpandFillFlags 
334              & CPU_TRANSFER_PAD_QWORD) && ((dwords * h) & 0x01);
335     (*infoRec->SetupForCPUToScreenColorExpandFill)(
336                                         pScrn, fg, bg, rop, planemask);
337     (*infoRec->SubsequentCPUToScreenColorExpandFill)(
338                                         pScrn, x, y, w, h, skipleft);
339
340     base = (CARD32*)infoRec->ColorExpandBase;
341
342 #ifndef FIXEDBASE
343     if((dwords * h) <= infoRec->ColorExpandRange)
344         while(h--) {
345             base = (*firstFunc)((CARD32*)srcp, base, dwords, shift);
346             srcp += srcwidth;
347         }
348     else
349 #endif
350         while(h--) {
351             (*firstFunc)((CARD32*)srcp, base, dwords, shift);
352             srcp += srcwidth;
353         }
354
355     if(flag){
356         base = (CARD32*)infoRec->ColorExpandBase;
357         base[0] = 0x00000000;
358     }
359
360     if(SecondPassColor != -1) {
361         h = H; /* Reset height */
362         fg = SecondPassColor;
363         SecondPassColor = -1;
364         firstFunc = secondFunc;
365         srcp = src;
366         goto SECOND_PASS;
367     }
368
369     if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND) 
370         (*infoRec->Sync)(pScrn);
371     else SET_SYNC_FLAG(infoRec);
372 }
373
374 #ifndef FIXEDBASE
375
376 void
377 #ifdef TRIPLE_BITS
378 EXPNAME(XAAWriteBitmapScanlineColorExpand3)(
379 #else
380 EXPNAME(XAAWriteBitmapScanlineColorExpand)(
381 #endif
382     ScrnInfoPtr pScrn,
383     int x, int y, int w, int h,
384     unsigned char *src,
385     int srcwidth,
386     int skipleft,
387     int fg, int bg,
388     int rop,
389     unsigned int planemask 
390 )
391 {
392     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
393     CARD32* base;
394     unsigned char *srcp = src;
395     int SecondPassColor = -1;
396     int shift = 0, dwords, bufferNo;
397     BitmapScanlineProcPtr firstFunc;
398     BitmapScanlineProcPtr secondFunc;
399
400 #ifdef TRIPLE_BITS
401     if((bg != -1) &&
402         ((infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) 
403         || ((infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) && 
404         (!CHECK_RGB_EQUAL(bg))))) {
405 #else
406     if((bg != -1) && 
407         (infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)){
408 #endif
409         if((rop == GXcopy) && infoRec->SetupForSolidFill) {
410             (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
411             (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
412         } else SecondPassColor = bg;
413         bg = -1;
414     }
415
416 #ifdef TRIPLE_BITS
417     if(skipleft) {
418 #else
419     if(skipleft && 
420         (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & 
421                 LEFT_EDGE_CLIPPING) || 
422         (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
423                  LEFT_EDGE_CLIPPING_NEGATIVE_X) && (skipleft > x)))) {
424 #endif
425         if((skipleft + ((w + 31) & ~31)) > ((skipleft + w + 31) & ~31)) {
426             /* don't read past the end */
427             firstFunc = BitmapScanline_Shifted_Careful;
428             secondFunc = BitmapScanline_Shifted_Inverted_Careful;
429         } else {
430             firstFunc = BitmapScanline_Shifted;
431             secondFunc = BitmapScanline_Shifted_Inverted;
432         }
433         shift = skipleft;
434         skipleft = 0;
435     } else {
436         firstFunc = BitmapScanline;
437         secondFunc = BitmapScanline_Inverted;
438         w += skipleft;
439         x -= skipleft;
440     }
441
442 #ifdef TRIPLE_BITS
443     dwords = (3 * w + 31) >> 5;
444 #else
445     dwords = (w + 31) >> 5;
446 #endif
447
448 SECOND_PASS:
449
450     (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn, fg, bg, rop, planemask);
451     (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
452                                         pScrn, x, y, w, h, skipleft);
453
454     bufferNo = 0;
455
456     while(h--) {
457         base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
458         (*firstFunc)((CARD32*)srcp, base, dwords, shift);
459         (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
460         srcp += srcwidth;
461         if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
462             bufferNo = 0;
463     }
464
465     if(SecondPassColor != -1) {
466         fg = SecondPassColor;
467         SecondPassColor = -1;
468         firstFunc = secondFunc;
469         srcp = src;
470         goto SECOND_PASS;
471     }
472
473     SET_SYNC_FLAG(infoRec);
474 }
475
476 #endif