First public contribution.
2 * $XFree86: xc/programs/Xserver/fb/fbpict.h,v 1.7 2001/07/18 10:15:02 keithp Exp $
4 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of Keith Packard not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission. Keith Packard makes no
13 * representations about the suitability of this software for any purpose. It
14 * is provided "as is" without express or implied warranty.
16 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
25 #ifdef HAVE_DIX_CONFIG_H
26 #include <dix-config.h>
32 //#include "renderedge.h"
34 #define FbIntMult(a,b,t) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) )
35 #define FbIntDiv(a,b) (((CARD16) (a) * 255) / (b))
37 #define FbGet8(v,i) ((CARD16) (CARD8) ((v) >> i))
40 * There are two ways of handling alpha -- either as a single unified value or
41 * a separate value for each component, hence each macro must have two
42 * versions. The unified alpha version has a 'U' at the end of the name,
43 * the component version has a 'C'. Similarly, functions which deal with
44 * this difference will have two versions using the same convention.
47 #define FbOverU(x,y,i,a,t) ((t) = FbIntMult(FbGet8(y,i),(a),(t)) + FbGet8(x,i),\
48 (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
50 #define FbOverC(x,y,i,a,t) ((t) = FbIntMult(FbGet8(y,i),FbGet8(a,i),(t)) + FbGet8(x,i),\
51 (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
53 #define FbInU(x,i,a,t) ((CARD32) FbIntMult(FbGet8(x,i),(a),(t)) << (i))
55 #define FbInC(x,i,a,t) ((CARD32) FbIntMult(FbGet8(x,i),FbGet8(a,i),(t)) << (i))
57 #define FbGen(x,y,i,ax,ay,t,u,v) ((t) = (FbIntMult(FbGet8(y,i),ay,(u)) + \
58 FbIntMult(FbGet8(x,i),ax,(v))),\
59 (CARD32) ((CARD8) ((t) | \
60 (0 - ((t) >> 8)))) << (i))
62 #define FbAdd(x,y,i,t) ((t) = FbGet8(x,i) + FbGet8(y,i), \
63 (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
66 #define Alpha(x) ((x) >> 24)
67 #define Red(x) (((x) >> 16) & 0xff)
68 #define Green(x) (((x) >> 8) & 0xff)
69 #define Blue(x) ((x) & 0xff)
71 #define fbComposeGetSolid(pict, bits, fmt) { \
73 FbStride __stride__; \
75 int __xoff__,__yoff__; \
77 fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
80 (bits) = *(CARD32 *) __bits__; \
83 (bits) = Fetch24 ((CARD8 *) __bits__); \
86 (bits) = *(CARD16 *) __bits__; \
87 (bits) = cvt0565to8888(bits); \
92 /* If necessary, convert RGB <--> BGR. */ \
93 if (PICT_FORMAT_TYPE((pict)->format) != PICT_FORMAT_TYPE(fmt)) \
95 (bits) = (((bits) & 0xff000000) | \
96 (((bits) & 0x00ff0000) >> 16) | \
97 (((bits) & 0x0000ff00) >> 0) | \
98 (((bits) & 0x000000ff) << 16)); \
100 /* manage missing src alpha */ \
101 if ((pict)->pFormat->direct.alphaMask == 0) \
102 (bits) |= 0xff000000; \
105 #define fbComposeGetStart(pict,x,y,type,stride,line,mul) {\
107 FbStride __stride__; \
109 int __xoff__,__yoff__; \
111 fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
112 (stride) = __stride__ * sizeof (FbBits) / sizeof (type); \
113 (line) = ((type *) __bits__) + (stride) * ((y) - __yoff__) + (mul) * ((x) - __xoff__); \
115 #define cvt8888to0565(s) ((((s) >> 3) & 0x001f) | \
116 (((s) >> 5) & 0x07e0) | \
117 (((s) >> 8) & 0xf800))
118 #define cvt0565to8888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
119 ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
120 ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
122 #if IMAGE_BYTE_ORDER == MSBFirst
123 #define Fetch24(a) ((unsigned long) (a) & 1 ? \
124 ((*(a) << 16) | *((CARD16 *) ((a)+1))) : \
125 ((*((CARD16 *) (a)) << 8) | *((a)+2)))
126 #define Store24(a,v) ((unsigned long) (a) & 1 ? \
127 ((*(a) = (CARD8) ((v) >> 16)), \
128 (*((CARD16 *) ((a)+1)) = (CARD16) (v))) : \
129 ((*((CARD16 *) (a)) = (CARD16) ((v) >> 8)), \
130 (*((a)+2) = (CARD8) (v))))
132 #define Fetch24(a) ((unsigned long) (a) & 1 ? \
133 ((*(a)) | (*((CARD16 *) ((a)+1)) << 8)) : \
134 ((*((CARD16 *) (a))) | (*((a)+2) << 16)))
135 #define Store24(a,v) ((unsigned long) (a) & 1 ? \
136 ((*(a) = (CARD8) (v)), \
137 (*((CARD16 *) ((a)+1)) = (CARD16) ((v) >> 8))) : \
138 ((*((CARD16 *) (a)) = (CARD16) (v)),\
139 (*((a)+2) = (CARD8) ((v) >> 16))))
143 The methods below use some tricks to be able to do two color
144 components at the same time.
148 x_c = (x_c * a) / 255
150 #define FbByteMul(x, a) do { \
151 CARD32 t = (x & 0xff00ff) *a; \
152 t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8; \
155 x = ((x >> 8) & 0xff00ff) * a; \
156 x = (x + ((x >> 8) & 0xff00ff) + 0x800080); \
162 x_c = (x_c * a) / 255 + y
164 #define FbByteMulAdd(x, a, y) do { \
165 CARD32 t = (x & 0xff00ff) * a; \
166 t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8; \
169 t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
172 x = ((x >> 8) & 0xff00ff) * a; \
173 x = (x + ((x >> 8) & 0xff00ff) + 0x800080) >> 8; \
175 x += (y >> 8) & 0xff00ff; \
176 x |= 0x1000100 - ((t >> 8) & 0xff00ff); \
183 x_c = (x_c * a + y_c * b) / 255
185 #define FbByteAddMul(x, a, y, b) do { \
187 CARD32 r = (x >> 24) * a + (y >> 24) * b; \
188 r += (r >> 8) + 0x80; \
191 t = (x & 0xff00) * a + (y & 0xff00) * b; \
192 t += (t >> 8) + 0x8000; \
196 t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
200 r = ((x >> 16) & 0xff) * a + ((y >> 16) & 0xff) * b; \
201 r += (r >> 8) + 0x80; \
204 x = (x & 0xff) * a + (y & 0xff) * b; \
205 x += (x >> 8) + 0x80; \
208 x |= 0x1000100 - ((x >> 8) & 0xff00ff); \
214 x_c = (x_c * a + y_c *b) / 256
216 #define FbByteAddMul_256(x, a, y, b) do { \
217 CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; \
221 x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; \
226 x_c = (x_c * a_c) / 255
228 #define FbByteMulC(x, a) do { \
230 CARD32 r = (x & 0xff) * (a & 0xff); \
231 r |= (x & 0xff0000) * ((a >> 16) & 0xff); \
232 r = (r + ((r >> 8) & 0xff00ff) + 0x800080) >> 8; \
236 t = (x & 0xff) * ((a >> 8) & 0xff); \
237 t |= (x & 0xff0000) * (a >> 24); \
238 t = (t + ((t >> 8) & 0xff00ff) + 0x800080); \
239 x = r | (t & 0xff00ff00); \
244 x_c = (x_c * a) / 255 + y
246 #define FbByteMulAddC(x, a, y) do { \
248 CARD32 r = (x & 0xff) * (a & 0xff); \
249 r |= (x & 0xff0000) * ((a >> 16) & 0xff); \
250 r = (r + ((r >> 8) & 0xff00ff) + 0x800080) >> 8; \
253 r |= 0x1000100 - ((r >> 8) & 0xff00ff); \
257 t = (x & 0xff) * ((a >> 8) & 0xff); \
258 t |= (x & 0xff0000) * (a >> 24); \
259 t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8; \
261 t += (y >> 8) & 0xff00ff; \
262 t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
268 x_c = (x_c * a_c + y_c * b) / 255
270 #define FbByteAddMulC(x, a, y, b) do { \
272 CARD32 r = (x >> 24) * (a >> 24) + (y >> 24) * b; \
273 r += (r >> 8) + 0x80; \
276 t = (x & 0xff00) * ((a >> 8) & 0xff) + (y & 0xff00) * b; \
277 t += (t >> 8) + 0x8000; \
281 t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
285 r = ((x >> 16) & 0xff) * ((a >> 16) & 0xff) + ((y >> 16) & 0xff) * b; \
286 r += (r >> 8) + 0x80; \
289 x = (x & 0xff) * (a & 0xff) + (y & 0xff) * b; \
290 x += (x >> 8) + 0x80; \
293 x |= 0x1000100 - ((x >> 8) & 0xff00ff); \
299 x_c = min(x_c + y_c, 255)
301 #define FbByteAdd(x, y) do { \
303 CARD32 r = (x & 0xff00ff) + (y & 0xff00ff); \
304 r |= 0x1000100 - ((r >> 8) & 0xff00ff); \
307 t = ((x >> 8) & 0xff00ff) + ((y >> 8) & 0xff00ff); \
308 t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
309 r |= (t & 0xff00ff) << 8; \
313 #define div_255(x) (((x) + ((x) >> 8) + 0x80) >> 8)
315 #if defined(__i386__) && defined(__GNUC__)
316 #define FASTCALL __attribute__((regparm(3)))
321 #if defined(__GNUC__)
322 #define INLINE __inline__
327 typedef struct _FbComposeData {
343 typedef FASTCALL void (*CombineMaskU) (CARD32 *src, const CARD32 *mask, int width);
344 typedef FASTCALL void (*CombineFuncU) (CARD32 *dest, const CARD32 *src, int width);
345 typedef FASTCALL void (*CombineFuncC) (CARD32 *dest, CARD32 *src, CARD32 *mask, int width);
347 typedef struct _FbComposeFunctions {
348 CombineFuncU *combineU;
349 CombineFuncC *combineC;
350 CombineMaskU combineMaskU;
351 } FbComposeFunctions;
356 fbCompositeGeneral (CARD8 op,
372 fbRasterizeEdges (FbBits *buf,
383 fbOver (CARD32 x, CARD32 y);
386 fbOver24 (CARD32 x, CARD32 y);
389 fbIn (CARD32 x, CARD8 y);
392 fbCompositeSolidMask_nx8x8888 (CARD8 op,
406 fbCompositeSolidMask_nx8x0888 (CARD8 op,
420 fbCompositeSolidMask_nx8888x8888C (CARD8 op,
434 fbCompositeSolidMask_nx8x0565 (CARD8 op,
448 fbCompositeSolidMask_nx8888x0565C (CARD8 op,
462 fbCompositeSrc_8888x8888 (CARD8 op,
476 fbCompositeSrc_8888x0888 (CARD8 op,
490 fbCompositeSrc_8888x0565 (CARD8 op,
504 fbCompositeSrc_0565x0565 (CARD8 op,
518 fbCompositeSrcAdd_8000x8000 (CARD8 op,
532 fbCompositeSrcAdd_8888x8888 (CARD8 op,
546 fbCompositeSrcAdd_1000x1000 (CARD8 op,
560 fbCompositeSolidMask_nx1xn (CARD8 op,
574 fbComposite (CARD8 op,
590 fbAddTraps (PicturePtr pPicture,
597 fbRasterizeTrapezoid (PicturePtr alpha,
603 fbAddTriangles (PicturePtr pPicture,
610 #endif /* _FBPICT_H_ */