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>
31 #include "renderedge.h"
35 #define INLINE __inline__
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)
78 * Returns TRUE if the fbComposeGetSolid can be used to get a single solid
79 * color representing every source sampling location of the picture.
82 fbCanGetSolid(PicturePtr pict
)
84 if (pict
->pDrawable
== NULL
||
85 pict
->pDrawable
->width
!= 1 ||
86 pict
->pDrawable
->height
!= 1)
90 if (pict
->repeat
!= RepeatNormal
)
93 switch (pict
->format
) {
108 #define fbComposeGetSolid(pict, bits, fmt) { \
110 FbStride __stride__; \
112 int __xoff__,__yoff__; \
114 fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
117 (bits) = READ((CARD32 *) __bits__); \
120 (bits) = Fetch24 ((CARD8 *) __bits__); \
123 (bits) = READ((CARD16 *) __bits__); \
124 (bits) = cvt0565to0888(bits); \
127 (bits) = READ((CARD8 *) __bits__); \
128 (bits) = (bits) << 24; \
131 (bits) = READ((CARD32 *) __bits__); \
132 (bits) = FbLeftStipBits((bits),1) ? 0xff000000 : 0x00000000;\
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) {\
153 FbStride __stride__; \
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))))
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))))
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; \
201 x = (((x >> 8) & 0xff00ff) * a) + 0x800080; \
202 x = (x + ((x >> 8) & 0xff00ff)); \
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; \
215 t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
218 x = (((x >> 8) & 0xff00ff) * a) + 0x800080; \
219 x = (x + ((x >> 8) & 0xff00ff)) >> 8; \
221 x += (y >> 8) & 0xff00ff; \
222 x |= 0x1000100 - ((x >> 8) & 0xff00ff); \
229 x_c = (x_c * a + y_c * b) / 255
231 #define FbByteAddMul(x, a, y, b) do { \
233 CARD32 r = (x >> 24) * a + (y >> 24) * b + 0x80; \
237 t = (x & 0xff00) * a + (y & 0xff00) * b; \
238 t += (t >> 8) + 0x8000; \
242 t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
246 r = ((x >> 16) & 0xff) * a + ((y >> 16) & 0xff) * b + 0x80; \
250 x = (x & 0xff) * a + (y & 0xff) * b + 0x80; \
254 x |= 0x1000100 - ((x >> 8) & 0xff00ff); \
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; \
267 x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; \
272 x_c = (x_c * a_c) / 255
274 #define FbByteMulC(x, a) do { \
276 CARD32 r = (x & 0xff) * (a & 0xff); \
277 r |= (x & 0xff0000) * ((a >> 16) & 0xff); \
279 r = (r + ((r >> 8) & 0xff00ff)) >> 8; \
283 t = (x & 0xff) * ((a >> 8) & 0xff); \
284 t |= (x & 0xff0000) * (a >> 24); \
286 t = t + ((t >> 8) & 0xff00ff); \
287 x = r | (t & 0xff00ff00); \
292 x_c = (x_c * a) / 255 + y
294 #define FbByteMulAddC(x, a, y) do { \
296 CARD32 r = (x & 0xff) * (a & 0xff); \
297 r |= (x & 0xff0000) * ((a >> 16) & 0xff); \
299 r = (r + ((r >> 8) & 0xff00ff)) >> 8; \
302 r |= 0x1000100 - ((r >> 8) & 0xff00ff); \
306 t = (x & 0xff) * ((a >> 8) & 0xff); \
307 t |= (x & 0xff0000) * (a >> 24); \
309 t = (t + ((t >> 8) & 0xff00ff)) >> 8; \
311 t += (y >> 8) & 0xff00ff; \
312 t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
318 x_c = (x_c * a_c + y_c * b) / 255
320 #define FbByteAddMulC(x, a, y, b) do { \
322 CARD32 r = (x >> 24) * (a >> 24) + (y >> 24) * b; \
323 r += (r >> 8) + 0x80; \
326 t = (x & 0xff00) * ((a >> 8) & 0xff) + (y & 0xff00) * b; \
327 t += (t >> 8) + 0x8000; \
331 t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
335 r = ((x >> 16) & 0xff) * ((a >> 16) & 0xff) + ((y >> 16) & 0xff) * b + 0x80; \
339 x = (x & 0xff) * (a & 0xff) + (y & 0xff) * b + 0x80; \
343 x |= 0x1000100 - ((x >> 8) & 0xff00ff); \
349 x_c = min(x_c + y_c, 255)
351 #define FbByteAdd(x, y) do { \
353 CARD32 r = (x & 0xff00ff) + (y & 0xff00ff); \
354 r |= 0x1000100 - ((r >> 8) & 0xff00ff); \
357 t = ((x >> 8) & 0xff00ff) + ((y >> 8) & 0xff00ff); \
358 t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
359 r |= (t & 0xff00ff) << 8; \
363 #define div_255(x) (((x) + 0x80 + (((x) + 0x80) >> 8)) >> 8)
365 #if defined(__i386__) && defined(__GNUC__)
366 #define FASTCALL __attribute__((regparm(3)))
371 typedef struct _FbComposeData
{
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
;
402 fbCompositeGeneral (CARD8 op
,
417 fbComposite (CARD8 op
,
430 typedef void (*CompositeFunc
) (CARD8 op
,
444 fbWalkCompositeRegion (CARD8 op
,
458 CompositeFunc compositeRect
);
463 fbAddTraps (PicturePtr pPicture
,
470 fbRasterizeTrapezoid (PicturePtr alpha
,
476 fbAddTriangles (PicturePtr pPicture
,
482 #endif /* _FBPICT_H_ */