First import
[xorg_rtime.git] / xorg-server-1.4 / fb / fbpict.h
blobb4c1dcf12d394c7efbe64d2a230d1578d7cfe93e
1 /*
3 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of Keith Packard not be used in
10 * advertising or publicity pertaining to distribution of the software without
11 * specific, written prior permission. Keith Packard makes no
12 * representations about the suitability of this software for any purpose. It
13 * is provided "as is" without express or implied warranty.
15 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21 * PERFORMANCE OF THIS SOFTWARE.
24 #ifdef HAVE_DIX_CONFIG_H
25 #include <dix-config.h>
26 #endif
28 #ifndef _FBPICT_H_
29 #define _FBPICT_H_
31 #include "renderedge.h"
34 #if defined(__GNUC__)
35 #define INLINE __inline__
36 #else
37 #define INLINE
38 #endif
40 #define FbIntMult(a,b,t) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) )
41 #define FbIntDiv(a,b) (((CARD16) (a) * 255) / (b))
43 #define FbGet8(v,i) ((CARD16) (CARD8) ((v) >> i))
46 * There are two ways of handling alpha -- either as a single unified value or
47 * a separate value for each component, hence each macro must have two
48 * versions. The unified alpha version has a 'U' at the end of the name,
49 * the component version has a 'C'. Similarly, functions which deal with
50 * this difference will have two versions using the same convention.
53 #define FbOverU(x,y,i,a,t) ((t) = FbIntMult(FbGet8(y,i),(a),(t)) + FbGet8(x,i),\
54 (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
56 #define FbOverC(x,y,i,a,t) ((t) = FbIntMult(FbGet8(y,i),FbGet8(a,i),(t)) + FbGet8(x,i),\
57 (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
59 #define FbInU(x,i,a,t) ((CARD32) FbIntMult(FbGet8(x,i),(a),(t)) << (i))
61 #define FbInC(x,i,a,t) ((CARD32) FbIntMult(FbGet8(x,i),FbGet8(a,i),(t)) << (i))
63 #define FbGen(x,y,i,ax,ay,t,u,v) ((t) = (FbIntMult(FbGet8(y,i),ay,(u)) + \
64 FbIntMult(FbGet8(x,i),ax,(v))),\
65 (CARD32) ((CARD8) ((t) | \
66 (0 - ((t) >> 8)))) << (i))
68 #define FbAdd(x,y,i,t) ((t) = FbGet8(x,i) + FbGet8(y,i), \
69 (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
72 #define Alpha(x) ((x) >> 24)
73 #define Red(x) (((x) >> 16) & 0xff)
74 #define Green(x) (((x) >> 8) & 0xff)
75 #define Blue(x) ((x) & 0xff)
77 /**
78 * Returns TRUE if the fbComposeGetSolid can be used to get a single solid
79 * color representing every source sampling location of the picture.
81 static INLINE Bool
82 fbCanGetSolid(PicturePtr pict)
84 if (pict->pDrawable == NULL ||
85 pict->pDrawable->width != 1 ||
86 pict->pDrawable->height != 1)
88 return FALSE;
90 if (pict->repeat != RepeatNormal)
91 return FALSE;
93 switch (pict->format) {
94 case PICT_a8r8g8b8:
95 case PICT_x8r8g8b8:
96 case PICT_a8b8g8r8:
97 case PICT_x8b8g8r8:
98 case PICT_r8g8b8:
99 case PICT_b8g8r8:
100 case PICT_r5g6b5:
101 case PICT_b5g6r5:
102 return TRUE;
103 default:
104 return FALSE;
108 #define fbComposeGetSolid(pict, bits, fmt) { \
109 FbBits *__bits__; \
110 FbStride __stride__; \
111 int __bpp__; \
112 int __xoff__,__yoff__; \
114 fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
115 switch (__bpp__) { \
116 case 32: \
117 (bits) = READ((CARD32 *) __bits__); \
118 break; \
119 case 24: \
120 (bits) = Fetch24 ((CARD8 *) __bits__); \
121 break; \
122 case 16: \
123 (bits) = READ((CARD16 *) __bits__); \
124 (bits) = cvt0565to0888(bits); \
125 break; \
126 case 8: \
127 (bits) = READ((CARD8 *) __bits__); \
128 (bits) = (bits) << 24; \
129 break; \
130 case 1: \
131 (bits) = READ((CARD32 *) __bits__); \
132 (bits) = FbLeftStipBits((bits),1) ? 0xff000000 : 0x00000000;\
133 break; \
134 default: \
135 return; \
137 /* If necessary, convert RGB <--> BGR. */ \
138 if (PICT_FORMAT_TYPE((pict)->format) != PICT_FORMAT_TYPE(fmt)) \
140 (bits) = (((bits) & 0xff000000) | \
141 (((bits) & 0x00ff0000) >> 16) | \
142 (((bits) & 0x0000ff00) >> 0) | \
143 (((bits) & 0x000000ff) << 16)); \
145 /* manage missing src alpha */ \
146 if ((pict)->pFormat->direct.alphaMask == 0) \
147 (bits) |= 0xff000000; \
148 fbFinishAccess ((pict)->pDrawable); \
151 #define fbComposeGetStart(pict,x,y,type,stride,line,mul) {\
152 FbBits *__bits__; \
153 FbStride __stride__; \
154 int __bpp__; \
155 int __xoff__,__yoff__; \
157 fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
158 (stride) = __stride__ * sizeof (FbBits) / sizeof (type); \
159 (line) = ((type *) __bits__) + (stride) * ((y) + __yoff__) + (mul) * ((x) + __xoff__); \
161 #define cvt8888to0565(s) ((((s) >> 3) & 0x001f) | \
162 (((s) >> 5) & 0x07e0) | \
163 (((s) >> 8) & 0xf800))
164 #define cvt0565to0888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
165 ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
166 ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
168 #if IMAGE_BYTE_ORDER == MSBFirst
169 #define Fetch24(a) ((unsigned long) (a) & 1 ? \
170 ((READ(a) << 16) | READ((CARD16 *) ((a)+1))) : \
171 ((READ((CARD16 *) (a)) << 8) | READ((a)+2)))
172 #define Store24(a,v) ((unsigned long) (a) & 1 ? \
173 (WRITE(a, (CARD8) ((v) >> 16)), \
174 WRITE((CARD16 *) ((a)+1), (CARD16) (v))) : \
175 (WRITE((CARD16 *) (a), (CARD16) ((v) >> 8)), \
176 WRITE((a)+2, (CARD8) (v))))
177 #else
178 #define Fetch24(a) ((unsigned long) (a) & 1 ? \
179 (READ(a) | (READ((CARD16 *) ((a)+1)) << 8)) : \
180 (READ((CARD16 *) (a)) | (READ((a)+2) << 16)))
181 #define Store24(a,v) ((unsigned long) (a) & 1 ? \
182 (WRITE(a, (CARD8) (v)), \
183 WRITE((CARD16 *) ((a)+1), (CARD16) ((v) >> 8))) : \
184 (WRITE((CARD16 *) (a), (CARD16) (v)),\
185 WRITE((a)+2, (CARD8) ((v) >> 16))))
186 #endif
189 The methods below use some tricks to be able to do two color
190 components at the same time.
194 x_c = (x_c * a) / 255
196 #define FbByteMul(x, a) do { \
197 CARD32 t = ((x & 0xff00ff) * a) + 0x800080; \
198 t = (t + ((t >> 8) & 0xff00ff)) >> 8; \
199 t &= 0xff00ff; \
201 x = (((x >> 8) & 0xff00ff) * a) + 0x800080; \
202 x = (x + ((x >> 8) & 0xff00ff)); \
203 x &= 0xff00ff00; \
204 x += t; \
205 } while (0)
208 x_c = (x_c * a) / 255 + y
210 #define FbByteMulAdd(x, a, y) do { \
211 CARD32 t = ((x & 0xff00ff) * a) + 0x800080; \
212 t = (t + ((t >> 8) & 0xff00ff)) >> 8; \
213 t &= 0xff00ff; \
214 t += y & 0xff00ff; \
215 t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
216 t &= 0xff00ff; \
218 x = (((x >> 8) & 0xff00ff) * a) + 0x800080; \
219 x = (x + ((x >> 8) & 0xff00ff)) >> 8; \
220 x &= 0xff00ff; \
221 x += (y >> 8) & 0xff00ff; \
222 x |= 0x1000100 - ((x >> 8) & 0xff00ff); \
223 x &= 0xff00ff; \
224 x <<= 8; \
225 x += t; \
226 } while (0)
229 x_c = (x_c * a + y_c * b) / 255
231 #define FbByteAddMul(x, a, y, b) do { \
232 CARD32 t; \
233 CARD32 r = (x >> 24) * a + (y >> 24) * b + 0x80; \
234 r += (r >> 8); \
235 r >>= 8; \
237 t = (x & 0xff00) * a + (y & 0xff00) * b; \
238 t += (t >> 8) + 0x8000; \
239 t >>= 16; \
241 t |= r << 16; \
242 t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
243 t &= 0xff00ff; \
244 t <<= 8; \
246 r = ((x >> 16) & 0xff) * a + ((y >> 16) & 0xff) * b + 0x80; \
247 r += (r >> 8); \
248 r >>= 8; \
250 x = (x & 0xff) * a + (y & 0xff) * b + 0x80; \
251 x += (x >> 8); \
252 x >>= 8; \
253 x |= r << 16; \
254 x |= 0x1000100 - ((x >> 8) & 0xff00ff); \
255 x &= 0xff00ff; \
256 x |= t; \
257 } while (0)
260 x_c = (x_c * a + y_c *b) / 256
262 #define FbByteAddMul_256(x, a, y, b) do { \
263 CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; \
264 t >>= 8; \
265 t &= 0xff00ff; \
267 x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; \
268 x &= 0xff00ff00; \
269 x += t; \
270 } while (0)
272 x_c = (x_c * a_c) / 255
274 #define FbByteMulC(x, a) do { \
275 CARD32 t; \
276 CARD32 r = (x & 0xff) * (a & 0xff); \
277 r |= (x & 0xff0000) * ((a >> 16) & 0xff); \
278 r += 0x800080; \
279 r = (r + ((r >> 8) & 0xff00ff)) >> 8; \
280 r &= 0xff00ff; \
282 x >>= 8; \
283 t = (x & 0xff) * ((a >> 8) & 0xff); \
284 t |= (x & 0xff0000) * (a >> 24); \
285 t += 0x800080; \
286 t = t + ((t >> 8) & 0xff00ff); \
287 x = r | (t & 0xff00ff00); \
289 } while (0)
292 x_c = (x_c * a) / 255 + y
294 #define FbByteMulAddC(x, a, y) do { \
295 CARD32 t; \
296 CARD32 r = (x & 0xff) * (a & 0xff); \
297 r |= (x & 0xff0000) * ((a >> 16) & 0xff); \
298 r += 0x800080; \
299 r = (r + ((r >> 8) & 0xff00ff)) >> 8; \
300 r &= 0xff00ff; \
301 r += y & 0xff00ff; \
302 r |= 0x1000100 - ((r >> 8) & 0xff00ff); \
303 r &= 0xff00ff; \
305 x >>= 8; \
306 t = (x & 0xff) * ((a >> 8) & 0xff); \
307 t |= (x & 0xff0000) * (a >> 24); \
308 t += 0x800080; \
309 t = (t + ((t >> 8) & 0xff00ff)) >> 8; \
310 t &= 0xff00ff; \
311 t += (y >> 8) & 0xff00ff; \
312 t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
313 t &= 0xff00ff; \
314 x = r | (t << 8); \
315 } while (0)
318 x_c = (x_c * a_c + y_c * b) / 255
320 #define FbByteAddMulC(x, a, y, b) do { \
321 CARD32 t; \
322 CARD32 r = (x >> 24) * (a >> 24) + (y >> 24) * b; \
323 r += (r >> 8) + 0x80; \
324 r >>= 8; \
326 t = (x & 0xff00) * ((a >> 8) & 0xff) + (y & 0xff00) * b; \
327 t += (t >> 8) + 0x8000; \
328 t >>= 16; \
330 t |= r << 16; \
331 t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
332 t &= 0xff00ff; \
333 t <<= 8; \
335 r = ((x >> 16) & 0xff) * ((a >> 16) & 0xff) + ((y >> 16) & 0xff) * b + 0x80; \
336 r += (r >> 8); \
337 r >>= 8; \
339 x = (x & 0xff) * (a & 0xff) + (y & 0xff) * b + 0x80; \
340 x += (x >> 8); \
341 x >>= 8; \
342 x |= r << 16; \
343 x |= 0x1000100 - ((x >> 8) & 0xff00ff); \
344 x &= 0xff00ff; \
345 x |= t; \
346 } while (0)
349 x_c = min(x_c + y_c, 255)
351 #define FbByteAdd(x, y) do { \
352 CARD32 t; \
353 CARD32 r = (x & 0xff00ff) + (y & 0xff00ff); \
354 r |= 0x1000100 - ((r >> 8) & 0xff00ff); \
355 r &= 0xff00ff; \
357 t = ((x >> 8) & 0xff00ff) + ((y >> 8) & 0xff00ff); \
358 t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
359 r |= (t & 0xff00ff) << 8; \
360 x = r; \
361 } while (0)
363 #define div_255(x) (((x) + 0x80 + (((x) + 0x80) >> 8)) >> 8)
365 #if defined(__i386__) && defined(__GNUC__)
366 #define FASTCALL __attribute__((regparm(3)))
367 #else
368 #define FASTCALL
369 #endif
371 typedef struct _FbComposeData {
372 CARD8 op;
373 PicturePtr src;
374 PicturePtr mask;
375 PicturePtr dest;
376 INT16 xSrc;
377 INT16 ySrc;
378 INT16 xMask;
379 INT16 yMask;
380 INT16 xDest;
381 INT16 yDest;
382 CARD16 width;
383 CARD16 height;
384 } FbComposeData;
386 void
387 fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer);
389 typedef FASTCALL void (*CombineMaskU) (CARD32 *src, const CARD32 *mask, int width);
390 typedef FASTCALL void (*CombineFuncU) (CARD32 *dest, const CARD32 *src, int width);
391 typedef FASTCALL void (*CombineFuncC) (CARD32 *dest, CARD32 *src, CARD32 *mask, int width);
393 typedef struct _FbComposeFunctions {
394 CombineFuncU *combineU;
395 CombineFuncC *combineC;
396 CombineMaskU combineMaskU;
397 } FbComposeFunctions;
399 /* fbcompose.c */
401 void
402 fbCompositeGeneral (CARD8 op,
403 PicturePtr pSrc,
404 PicturePtr pMask,
405 PicturePtr pDst,
406 INT16 xSrc,
407 INT16 ySrc,
408 INT16 xMask,
409 INT16 yMask,
410 INT16 xDst,
411 INT16 yDst,
412 CARD16 width,
413 CARD16 height);
415 /* fbpict.c */
416 void
417 fbComposite (CARD8 op,
418 PicturePtr pSrc,
419 PicturePtr pMask,
420 PicturePtr pDst,
421 INT16 xSrc,
422 INT16 ySrc,
423 INT16 xMask,
424 INT16 yMask,
425 INT16 xDst,
426 INT16 yDst,
427 CARD16 width,
428 CARD16 height);
430 typedef void (*CompositeFunc) (CARD8 op,
431 PicturePtr pSrc,
432 PicturePtr pMask,
433 PicturePtr pDst,
434 INT16 xSrc,
435 INT16 ySrc,
436 INT16 xMask,
437 INT16 yMask,
438 INT16 xDst,
439 INT16 yDst,
440 CARD16 width,
441 CARD16 height);
443 void
444 fbWalkCompositeRegion (CARD8 op,
445 PicturePtr pSrc,
446 PicturePtr pMask,
447 PicturePtr pDst,
448 INT16 xSrc,
449 INT16 ySrc,
450 INT16 xMask,
451 INT16 yMask,
452 INT16 xDst,
453 INT16 yDst,
454 CARD16 width,
455 CARD16 height,
456 Bool srcRepeat,
457 Bool maskRepeat,
458 CompositeFunc compositeRect);
460 /* fbtrap.c */
462 void
463 fbAddTraps (PicturePtr pPicture,
464 INT16 xOff,
465 INT16 yOff,
466 int ntrap,
467 xTrap *traps);
469 void
470 fbRasterizeTrapezoid (PicturePtr alpha,
471 xTrapezoid *trap,
472 int x_off,
473 int y_off);
475 void
476 fbAddTriangles (PicturePtr pPicture,
477 INT16 xOff,
478 INT16 yOff,
479 int ntri,
480 xTriangle *tris);
482 #endif /* _FBPICT_H_ */