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) {
110
#define fbComposeGetSolid(pict, bits, fmt) { \
112
FbStride __stride__; \
114
int __xoff__,__yoff__; \
116
fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
119
(bits) = READ((CARD32 *) __bits__); \
122
(bits) = Fetch24 ((CARD8 *) __bits__); \
125
(bits) = READ((CARD16 *) __bits__); \
126
(bits) = cvt0565to0888(bits); \
129
(bits) = READ((CARD8 *) __bits__); \
130
(bits) = (bits) << 24; \
133
(bits) = READ((CARD32 *) __bits__); \
134
(bits) = FbLeftStipBits((bits),1) ? 0xff000000 : 0x00000000;\
139
/* If necessary, convert RGB <--> BGR. */ \
140
if (PICT_FORMAT_TYPE((pict)->format) != PICT_FORMAT_TYPE(fmt)) \
142
(bits) = (((bits) & 0xff000000) | \
143
(((bits) & 0x00ff0000) >> 16) | \
144
(((bits) & 0x0000ff00) >> 0) | \
145
(((bits) & 0x000000ff) << 16)); \
147
/* manage missing src alpha */ \
148
if ((pict)->pFormat->direct.alphaMask == 0) \
149
(bits) |= 0xff000000; \
150
fbFinishAccess ((pict)->pDrawable); \
153
#define fbComposeGetStart(pict,x,y,type,stride,line,mul) {\
155
FbStride __stride__; \
157
int __xoff__,__yoff__; \
159
fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
160
(stride) = __stride__ * sizeof (FbBits) / sizeof (type); \
161
(line) = ((type *) __bits__) + (stride) * ((y) + __yoff__) + (mul) * ((x) + __xoff__); \
163
#define cvt8888to0565(s) ((((s) >> 3) & 0x001f) | \
164
(((s) >> 5) & 0x07e0) | \
165
(((s) >> 8) & 0xf800))
166
#define cvt0565to0888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
167
((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
168
((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
170
#if IMAGE_BYTE_ORDER == MSBFirst
171
#define Fetch24(a) ((unsigned long) (a) & 1 ? \
172
((READ(a) << 16) | READ((CARD16 *) ((a)+1))) : \
173
((READ((CARD16 *) (a)) << 8) | READ((a)+2)))
174
#define Store24(a,v) ((unsigned long) (a) & 1 ? \
175
(WRITE(a, (CARD8) ((v) >> 16)), \
176
WRITE((CARD16 *) ((a)+1), (CARD16) (v))) : \
177
(WRITE((CARD16 *) (a), (CARD16) ((v) >> 8)), \
178
WRITE((a)+2, (CARD8) (v))))
180
#define Fetch24(a) ((unsigned long) (a) & 1 ? \
181
(READ(a) | (READ((CARD16 *) ((a)+1)) << 8)) : \
182
(READ((CARD16 *) (a)) | (READ((a)+2) << 16)))
183
#define Store24(a,v) ((unsigned long) (a) & 1 ? \
184
(WRITE(a, (CARD8) (v)), \
185
WRITE((CARD16 *) ((a)+1), (CARD16) ((v) >> 8))) : \
186
(WRITE((CARD16 *) (a), (CARD16) (v)),\
187
WRITE((a)+2, (CARD8) ((v) >> 16))))
191
The methods below use some tricks to be able to do two color
192
components at the same time.
196
x_c = (x_c * a) / 255
198
#define FbByteMul(x, a) do { \
199
CARD32 t = ((x & 0xff00ff) * a) + 0x800080; \
200
t = (t + ((t >> 8) & 0xff00ff)) >> 8; \
203
x = (((x >> 8) & 0xff00ff) * a) + 0x800080; \
204
x = (x + ((x >> 8) & 0xff00ff)); \
210
x_c = (x_c * a) / 255 + y
212
#define FbByteMulAdd(x, a, y) do { \
213
CARD32 t = ((x & 0xff00ff) * a) + 0x800080; \
214
t = (t + ((t >> 8) & 0xff00ff)) >> 8; \
217
t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
220
x = (((x >> 8) & 0xff00ff) * a) + 0x800080; \
221
x = (x + ((x >> 8) & 0xff00ff)) >> 8; \
223
x += (y >> 8) & 0xff00ff; \
224
x |= 0x1000100 - ((x >> 8) & 0xff00ff); \
231
x_c = (x_c * a + y_c * b) / 255
233
#define FbByteAddMul(x, a, y, b) do { \
235
CARD32 r = (x >> 24) * a + (y >> 24) * b + 0x80; \
239
t = (x & 0xff00) * a + (y & 0xff00) * b; \
240
t += (t >> 8) + 0x8000; \
244
t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
248
r = ((x >> 16) & 0xff) * a + ((y >> 16) & 0xff) * b + 0x80; \
252
x = (x & 0xff) * a + (y & 0xff) * b + 0x80; \
256
x |= 0x1000100 - ((x >> 8) & 0xff00ff); \
262
x_c = (x_c * a + y_c *b) / 256
264
#define FbByteAddMul_256(x, a, y, b) do { \
265
CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; \
269
x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; \
274
x_c = (x_c * a_c) / 255
276
#define FbByteMulC(x, a) do { \
278
CARD32 r = (x & 0xff) * (a & 0xff); \
279
r |= (x & 0xff0000) * ((a >> 16) & 0xff); \
281
r = (r + ((r >> 8) & 0xff00ff)) >> 8; \
285
t = (x & 0xff) * ((a >> 8) & 0xff); \
286
t |= (x & 0xff0000) * (a >> 24); \
288
t = t + ((t >> 8) & 0xff00ff); \
289
x = r | (t & 0xff00ff00); \
294
x_c = (x_c * a) / 255 + y
296
#define FbByteMulAddC(x, a, y) do { \
298
CARD32 r = (x & 0xff) * (a & 0xff); \
299
r |= (x & 0xff0000) * ((a >> 16) & 0xff); \
301
r = (r + ((r >> 8) & 0xff00ff)) >> 8; \
304
r |= 0x1000100 - ((r >> 8) & 0xff00ff); \
308
t = (x & 0xff) * ((a >> 8) & 0xff); \
309
t |= (x & 0xff0000) * (a >> 24); \
311
t = (t + ((t >> 8) & 0xff00ff)) >> 8; \
313
t += (y >> 8) & 0xff00ff; \
314
t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
320
x_c = (x_c * a_c + y_c * b) / 255
322
#define FbByteAddMulC(x, a, y, b) do { \
324
CARD32 r = (x >> 24) * (a >> 24) + (y >> 24) * b; \
325
r += (r >> 8) + 0x80; \
328
t = (x & 0xff00) * ((a >> 8) & 0xff) + (y & 0xff00) * b; \
329
t += (t >> 8) + 0x8000; \
333
t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
337
r = ((x >> 16) & 0xff) * ((a >> 16) & 0xff) + ((y >> 16) & 0xff) * b + 0x80; \
341
x = (x & 0xff) * (a & 0xff) + (y & 0xff) * b + 0x80; \
345
x |= 0x1000100 - ((x >> 8) & 0xff00ff); \
351
x_c = min(x_c + y_c, 255)
353
#define FbByteAdd(x, y) do { \
355
CARD32 r = (x & 0xff00ff) + (y & 0xff00ff); \
356
r |= 0x1000100 - ((r >> 8) & 0xff00ff); \
359
t = ((x >> 8) & 0xff00ff) + ((y >> 8) & 0xff00ff); \
360
t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
361
r |= (t & 0xff00ff) << 8; \
365
#define div_255(x) (((x) + 0x80 + (((x) + 0x80) >> 8)) >> 8)
367
#if defined(__i386__) && defined(__GNUC__)
368
#define FASTCALL __attribute__((regparm(3)))
373
typedef struct _FbComposeData {
388
extern _X_EXPORT void
389
fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer);
391
typedef FASTCALL void (*CombineMaskU) (CARD32 *src, const CARD32 *mask, int width);
392
typedef FASTCALL void (*CombineFuncU) (CARD32 *dest, const CARD32 *src, int width);
393
typedef FASTCALL void (*CombineFuncC) (CARD32 *dest, CARD32 *src, CARD32 *mask, int width);
395
typedef struct _FbComposeFunctions {
396
CombineFuncU *combineU;
397
CombineFuncC *combineC;
398
CombineMaskU combineMaskU;
399
} FbComposeFunctions;
403
extern _X_EXPORT void
404
fbCompositeGeneral (CARD8 op,
418
32
extern _X_EXPORT void
419
33
fbComposite (CARD8 op,