~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to cfb/cfbmskbits.h

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XFree86: xc/programs/Xserver/cfb/cfbmskbits.h,v 3.13tsi Exp $ */
 
2
/************************************************************
 
3
Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
 
4
 
 
5
                    All Rights Reserved
 
6
 
 
7
Permission  to  use,  copy,  modify,  and  distribute   this
 
8
software  and  its documentation for any purpose and without
 
9
fee is hereby granted, provided that the above copyright no-
 
10
tice  appear  in all copies and that both that copyright no-
 
11
tice and this permission notice appear in  supporting  docu-
 
12
mentation,  and  that the names of Sun or The Open Group
 
13
not be used in advertising or publicity pertaining to 
 
14
distribution  of  the software  without specific prior 
 
15
written permission. Sun and The Open Group make no 
 
16
representations about the suitability of this software for 
 
17
any purpose. It is provided "as is" without any express or 
 
18
implied warranty.
 
19
 
 
20
SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
 
21
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 
22
NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
 
23
ABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 
24
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
 
25
PROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
 
26
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
 
27
THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
28
 
 
29
********************************************************/
 
30
 
 
31
/* $Xorg: cfbmskbits.h,v 1.3 2000/08/17 19:48:14 cpqbld Exp $ */
 
32
/* Optimizations for PSZ == 32 added by Kyle Marvin (marvin@vitec.com) */
 
33
 
 
34
#include        <X11/X.h>
 
35
#include        <X11/Xmd.h>
 
36
#include        "servermd.h"
 
37
#if defined(XFREE86) || ( defined(__OpenBSD__) && defined(__alpha__) ) \
 
38
        || (defined(__bsdi__))
 
39
#include        "xf86_ansic.h"
 
40
#include        "compiler.h"
 
41
#endif
 
42
 
 
43
/*
 
44
 * ==========================================================================
 
45
 * Converted from mfb to support memory-mapped color framebuffer by smarks@sun, 
 
46
 * April-May 1987.
 
47
 *
 
48
 * The way I did the conversion was to consider each longword as an
 
49
 * array of four bytes instead of an array of 32 one-bit pixels.  So
 
50
 * getbits() and putbits() retain much the same calling sequence, but
 
51
 * they move bytes around instead of bits.  Of course, this entails the
 
52
 * removal of all of the one-bit-pixel dependencies from the other
 
53
 * files, but the major bit-hacking stuff should be covered here.
 
54
 *
 
55
 * I've created some new macros that make it easier to understand what's 
 
56
 * going on in the pixel calculations, and that make it easier to change the 
 
57
 * pixel size.
 
58
 *
 
59
 * name     explanation
 
60
 * ----     -----------
 
61
 * PSZ      pixel size (in bits)
 
62
 * PGSZ     pixel group size (in bits)
 
63
 * PGSZB    pixel group size (in bytes)
 
64
 * PGSZBMSK mask with lowest PGSZB bits set to 1
 
65
 * PPW      pixels per word (pixels per pixel group)
 
66
 * PPWMSK   mask with lowest PPW bits set to 1
 
67
 * PLST     index of last pixel in a word (should be PPW-1)
 
68
 * PIM      pixel index mask (index within a pixel group)
 
69
 * PWSH     pixel-to-word shift (should be log2(PPW))
 
70
 * PMSK     mask with lowest PSZ bits set to 1
 
71
 *
 
72
 *
 
73
 * Here are some sample values.  In the notation cfbA,B: A is PSZ, and
 
74
 * B is PGSZB.  All the other values are derived from these
 
75
 * two.  This table does not show all combinations!
 
76
 *
 
77
 * name     cfb8,4    cfb24,4      cfb32,4    cfb8,8    cfb24,8    cfb32,8
 
78
 * ----     ------    -------      ------     ------    ------     -------
 
79
 * PSZ        8         24           32          8        24         32
 
80
 * PGSZ      32         32           32         64        64         64
 
81
 * PGSZB      4          4            4          8         8          8
 
82
 * PGSZBMSK 0xF        0xF?         0xF        0xFF      0xFF       0xFF
 
83
 * PPW        4          1            1          8         2          2
 
84
 * PPWMSK   0xF        0x1          0x1        0xFF       0x3?       0x3    
 
85
 * PLST       3          0            0          7         1          1
 
86
 * PIM      0x3        0x0          0x0        0x7       0x1?        0x1
 
87
 * PWSH       2          0            0          3         1          1
 
88
 * PMSK     0xFF      0xFFFFFF     0xFFFFFFFF 0xFF      0xFFFFFF   0xFFFFFFFF
 
89
 *
 
90
 *
 
91
 * I have also added a new macro, PFILL, that takes one pixel and
 
92
 * replicates it throughout a word.  This macro definition is dependent
 
93
 * upon pixel and word size; it doesn't use macros like PPW and so
 
94
 * forth.  Examples: for monochrome, PFILL(1) => 0xffffffff, PFILL(0) =>
 
95
 * 0x00000000.  For 8-bit color, PFILL(0x5d) => 0x5d5d5d5d.  This macro
 
96
 * is used primarily for replicating a plane mask into a word.
 
97
 *
 
98
 * Color framebuffers operations also support the notion of a plane
 
99
 * mask.  This mask determines which planes of the framebuffer can be
 
100
 * altered; the others are left unchanged.  I have added another
 
101
 * parameter to the putbits and putbitsrop macros that is the plane
 
102
 * mask.
 
103
 * ==========================================================================
 
104
 *
 
105
 * Keith Packard (keithp@suse.com)
 
106
 * 64bit code is no longer supported; it requires DIX support
 
107
 * for repadding images which significantly impacts performance
 
108
 */
 
109
 
 
110
/*
 
111
 *  PSZ needs to be defined before we get here.  Usually it comes from a
 
112
 *  -DPSZ=foo on the compilation command line.
 
113
 */
 
114
 
 
115
#ifndef PSZ
 
116
#define PSZ 8
 
117
#endif
 
118
 
 
119
/*
 
120
 *  PixelGroup is the data type used to operate on groups of pixels.
 
121
 *  We typedef it here to CARD32 with the assumption that you
 
122
 *  want to manipulate 32 bits worth of pixels at a time as you can.  If CARD32
 
123
 *  is not appropriate for your server, define it to something else
 
124
 *  before including this file.  In this case you will also have to define
 
125
 *  PGSZB to the size in bytes of PixelGroup.
 
126
 */
 
127
#ifndef PixelGroup
 
128
#define PixelGroup CARD32
 
129
#define PGSZB 4
 
130
#endif /* PixelGroup */
 
131
    
 
132
#ifndef CfbBits
 
133
#define CfbBits CARD32
 
134
#endif
 
135
 
 
136
#define PGSZ    (PGSZB << 3)
 
137
#define PPW     (PGSZ/PSZ)
 
138
#define PLST    (PPW-1)
 
139
#define PIM     PLST
 
140
#define PMSK    (((PixelGroup)1 << PSZ) - 1)
 
141
#define PPWMSK  (((PixelGroup)1 << PPW) - 1) /* instead of BITMSK */
 
142
#define PGSZBMSK (((PixelGroup)1 << PGSZB) - 1)
 
143
 
 
144
/*  set PWSH = log2(PPW) using brute force */
 
145
 
 
146
#if PPW == 1
 
147
#define PWSH 0
 
148
#else
 
149
#if PPW == 2
 
150
#define PWSH 1
 
151
#else
 
152
#if PPW == 4
 
153
#define PWSH 2
 
154
#else
 
155
#if PPW == 8
 
156
#define PWSH 3
 
157
#else
 
158
#if PPW == 16
 
159
#define PWSH 4
 
160
#endif /* PPW == 16 */
 
161
#endif /* PPW == 8 */
 
162
#endif /* PPW == 4 */
 
163
#endif /* PPW == 2 */
 
164
#endif /* PPW == 1 */
 
165
 
 
166
/*  Defining PIXEL_ADDR means that individual pixels are addressable by this
 
167
 *  machine (as type PixelType).  A possible CFB architecture which supported
 
168
 *  8-bits-per-pixel on a non byte-addressable machine would not have this
 
169
 *  defined.
 
170
 *
 
171
 *  Defining FOUR_BIT_CODE means that cfb knows how to stipple on this machine;
 
172
 *  eventually, stippling code for 16 and 32 bit devices should be written
 
173
 *  which would allow them to also use FOUR_BIT_CODE.  There isn't that
 
174
 *  much to do in those cases, but it would make them quite a bit faster.
 
175
 */
 
176
 
 
177
#if PSZ == 8
 
178
#define PIXEL_ADDR
 
179
typedef CARD8 PixelType;
 
180
#define FOUR_BIT_CODE
 
181
#endif
 
182
 
 
183
#if PSZ == 16
 
184
#define PIXEL_ADDR
 
185
typedef CARD16 PixelType;
 
186
#endif
 
187
 
 
188
#if PSZ == 24
 
189
#undef PMSK
 
190
#define PMSK    0xFFFFFF
 
191
/*#undef PIM
 
192
#define PIM 3*/
 
193
#define PIXEL_ADDR
 
194
typedef CARD32 PixelType;
 
195
#endif
 
196
 
 
197
#if PSZ == 32
 
198
#undef PMSK
 
199
#define PMSK    0xFFFFFFFF
 
200
#define PIXEL_ADDR
 
201
typedef CARD32 PixelType;
 
202
#endif
 
203
 
 
204
 
 
205
/* the following notes use the following conventions:
 
206
SCREEN LEFT                             SCREEN RIGHT
 
207
in this file and maskbits.c, left and right refer to screen coordinates,
 
208
NOT bit numbering in registers.
 
209
 
 
210
cfbstarttab[n] 
 
211
        pixels[0,n-1] = 0's     pixels[n,PPW-1] = 1's
 
212
cfbendtab[n] =
 
213
        pixels[0,n-1] = 1's     pixels[n,PPW-1] = 0's
 
214
 
 
215
cfbstartpartial[], cfbendpartial[]
 
216
        these are used as accelerators for doing putbits and masking out
 
217
bits that are all contained between longword boudaries.  the extra
 
218
256 bytes of data seems a small price to pay -- code is smaller,
 
219
and narrow things (e.g. window borders) go faster.
 
220
 
 
221
the names may seem misleading; they are derived not from which end
 
222
of the word the bits are turned on, but at which end of a scanline
 
223
the table tends to be used.
 
224
 
 
225
look at the tables and macros to understand boundary conditions.
 
226
(careful readers will note that starttab[n] = ~endtab[n] for n != 0)
 
227
 
 
228
-----------------------------------------------------------------------
 
229
these two macros depend on the screen's bit ordering.
 
230
in both of them x is a screen position.  they are used to
 
231
combine bits collected from multiple longwords into a
 
232
single destination longword, and to unpack a single
 
233
source longword into multiple destinations.
 
234
 
 
235
SCRLEFT(dst, x)
 
236
        takes dst[x, PPW] and moves them to dst[0, PPW-x]
 
237
        the contents of the rest of dst are 0 ONLY IF
 
238
        dst is UNSIGNED.
 
239
        is cast as an unsigned.
 
240
        this is a right shift on the VAX, left shift on
 
241
        Sun and pc-rt.
 
242
 
 
243
SCRRIGHT(dst, x)
 
244
        takes dst[0,x] and moves them to dst[PPW-x, PPW]
 
245
        the contents of the rest of dst are 0 ONLY IF
 
246
        dst is UNSIGNED.
 
247
        this is a left shift on the VAX, right shift on
 
248
        Sun and pc-rt.
 
249
 
 
250
 
 
251
the remaining macros are cpu-independent; all bit order dependencies
 
252
are built into the tables and the two macros above.
 
253
 
 
254
maskbits(x, w, startmask, endmask, nlw)
 
255
        for a span of width w starting at position x, returns
 
256
a mask for ragged pixels at start, mask for ragged pixels at end,
 
257
and the number of whole longwords between the ends.
 
258
 
 
259
maskpartialbits(x, w, mask)
 
260
        works like maskbits(), except all the pixels are in the
 
261
        same longword (i.e. (x&0xPIM + w) <= PPW)
 
262
 
 
263
mask32bits(x, w, startmask, endmask, nlw)
 
264
        as maskbits, but does not calculate nlw.  it is used by
 
265
        cfbGlyphBlt to put down glyphs <= PPW bits wide.
 
266
 
 
267
getbits(psrc, x, w, dst)
 
268
        starting at position x in psrc (x < PPW), collect w
 
269
        pixels and put them in the screen left portion of dst.
 
270
        psrc is a longword pointer.  this may span longword boundaries.
 
271
        it special-cases fetching all w bits from one longword.
 
272
 
 
273
        +--------+--------+             +--------+
 
274
        |    | m |n|      |     ==>     | m |n|  |
 
275
        +--------+--------+             +--------+
 
276
            x      x+w                  0     w
 
277
        psrc     psrc+1                 dst
 
278
                        m = PPW - x
 
279
                        n = w - m
 
280
 
 
281
        implementation:
 
282
        get m pixels, move to screen-left of dst, zeroing rest of dst;
 
283
        get n pixels from next word, move screen-right by m, zeroing
 
284
                 lower m pixels of word.
 
285
        OR the two things together.
 
286
 
 
287
putbits(src, x, w, pdst, planemask)
 
288
        starting at position x in pdst, put down the screen-leftmost
 
289
        w bits of src.  pdst is a longword pointer.  this may
 
290
        span longword boundaries.
 
291
        it special-cases putting all w bits into the same longword.
 
292
 
 
293
        +--------+                      +--------+--------+
 
294
        | m |n|  |              ==>     |    | m |n|      |
 
295
        +--------+                      +--------+--------+
 
296
        0     w                              x     x+w
 
297
        dst                             pdst     pdst+1
 
298
                        m = PPW - x
 
299
                        n = w - m
 
300
 
 
301
        implementation:
 
302
        get m pixels, shift screen-right by x, zero screen-leftmost x
 
303
                pixels; zero rightmost m bits of *pdst and OR in stuff
 
304
                from before the semicolon.
 
305
        shift src screen-left by m, zero bits n-32;
 
306
                zero leftmost n pixels of *(pdst+1) and OR in the
 
307
                stuff from before the semicolon.
 
308
 
 
309
putbitsrop(src, x, w, pdst, planemask, ROP)
 
310
        like putbits but calls DoRop with the rasterop ROP (see cfb.h for
 
311
        DoRop)
 
312
 
 
313
getleftbits(psrc, w, dst)
 
314
        get the leftmost w (w<=PPW) bits from *psrc and put them
 
315
        in dst.  this is used by the cfbGlyphBlt code for glyphs
 
316
        <=PPW bits wide.
 
317
*/
 
318
 
 
319
#if     (BITMAP_BIT_ORDER == MSBFirst)
 
320
#define BitRight(lw,n)  ((lw) >> (n))
 
321
#define BitLeft(lw,n)   ((lw) << (n))
 
322
#else   /* (BITMAP_BIT_ORDER == LSBFirst) */
 
323
#define BitRight(lw,n)  ((lw) << (n))
 
324
#define BitLeft(lw,n)   ((lw) >> (n))
 
325
#endif  /* (BITMAP_BIT_ORDER == MSBFirst) */
 
326
 
 
327
#define SCRLEFT(lw, n)  BitLeft (lw, (n) * PSZ)
 
328
#define SCRRIGHT(lw, n) BitRight(lw, (n) * PSZ)
 
329
 
 
330
/*
 
331
 * Note that the shift direction is independent of the byte ordering of the 
 
332
 * machine.  The following is portable code.
 
333
 */
 
334
#if PPW == 16
 
335
#define PFILL(p) ( ((p)&PMSK)          | \
 
336
                   ((p)&PMSK) <<   PSZ | \
 
337
                   ((p)&PMSK) << 2*PSZ | \
 
338
                   ((p)&PMSK) << 3*PSZ | \
 
339
                   ((p)&PMSK) << 4*PSZ | \
 
340
                   ((p)&PMSK) << 5*PSZ | \
 
341
                   ((p)&PMSK) << 6*PSZ | \
 
342
                   ((p)&PMSK) << 7*PSZ | \
 
343
                   ((p)&PMSK) << 8*PSZ | \
 
344
                   ((p)&PMSK) << 9*PSZ | \
 
345
                   ((p)&PMSK) << 10*PSZ | \
 
346
                   ((p)&PMSK) << 11*PSZ | \
 
347
                   ((p)&PMSK) << 12*PSZ | \
 
348
                   ((p)&PMSK) << 13*PSZ | \
 
349
                   ((p)&PMSK) << 14*PSZ | \
 
350
                   ((p)&PMSK) << 15*PSZ ) 
 
351
#define PFILL2(p, pf) { \
 
352
    pf = (p) & PMSK; \
 
353
    pf |= (pf << PSZ); \
 
354
    pf |= (pf << 2*PSZ); \
 
355
    pf |= (pf << 4*PSZ); \
 
356
    pf |= (pf << 8*PSZ); \
 
357
}
 
358
#endif /* PPW == 16 */
 
359
#if PPW == 8
 
360
#define PFILL(p) ( ((p)&PMSK)          | \
 
361
                   ((p)&PMSK) <<   PSZ | \
 
362
                   ((p)&PMSK) << 2*PSZ | \
 
363
                   ((p)&PMSK) << 3*PSZ | \
 
364
                   ((p)&PMSK) << 4*PSZ | \
 
365
                   ((p)&PMSK) << 5*PSZ | \
 
366
                   ((p)&PMSK) << 6*PSZ | \
 
367
                   ((p)&PMSK) << 7*PSZ )
 
368
#define PFILL2(p, pf) { \
 
369
    pf = (p) & PMSK; \
 
370
    pf |= (pf << PSZ); \
 
371
    pf |= (pf << 2*PSZ); \
 
372
    pf |= (pf << 4*PSZ); \
 
373
}
 
374
#endif
 
375
#if PPW == 4
 
376
#define PFILL(p) ( ((p)&PMSK)          | \
 
377
                   ((p)&PMSK) <<   PSZ | \
 
378
                   ((p)&PMSK) << 2*PSZ | \
 
379
                   ((p)&PMSK) << 3*PSZ )
 
380
#define PFILL2(p, pf) { \
 
381
    pf = (p) & PMSK; \
 
382
    pf |= (pf << PSZ); \
 
383
    pf |= (pf << 2*PSZ); \
 
384
}
 
385
#endif
 
386
#if PPW == 2
 
387
#define PFILL(p) ( ((p)&PMSK)          | \
 
388
                   ((p)&PMSK) <<   PSZ )
 
389
#define PFILL2(p, pf) { \
 
390
    pf = (p) & PMSK; \
 
391
    pf |= (pf << PSZ); \
 
392
}
 
393
#endif
 
394
#if PPW == 1
 
395
#define PFILL(p)        (p)
 
396
#define PFILL2(p,pf)    (pf = (p))
 
397
#endif
 
398
 
 
399
/*
 
400
 * Reduced raster op - using precomputed values, perform the above
 
401
 * in three instructions
 
402
 */
 
403
 
 
404
#define DoRRop(dst, and, xor)   (((dst) & (and)) ^ (xor))
 
405
 
 
406
#define DoMaskRRop(dst, and, xor, mask) \
 
407
    (((dst) & ((and) | ~(mask))) ^ (xor & mask))
 
408
 
 
409
#if PSZ != 32 || PPW != 1
 
410
 
 
411
# if (PSZ == 24 && PPW == 1)
 
412
#define maskbits(x, w, startmask, endmask, nlw) {\
 
413
    startmask = cfbstarttab[(x)&3]; \
 
414
    endmask = cfbendtab[((x)+(w)) & 3]; \
 
415
    nlw = ((((x)+(w))*3)>>2) - (((x)*3 +3)>>2); \
 
416
}
 
417
 
 
418
#define mask32bits(x, w, startmask, endmask) \
 
419
    startmask = cfbstarttab[(x)&3]; \
 
420
    endmask = cfbendtab[((x)+(w)) & 3];
 
421
 
 
422
#define maskpartialbits(x, w, mask) \
 
423
    mask = cfbstartpartial[(x) & 3] & cfbendpartial[((x)+(w)) & 3];
 
424
 
 
425
#define maskbits24(x, w, startmask, endmask, nlw) \
 
426
    startmask = cfbstarttab24[(x) & 3]; \
 
427
    endmask = cfbendtab24[((x)+(w)) & 3]; \
 
428
    if (startmask){ \
 
429
        nlw = (((w) - (4 - ((x) & 3))) >> 2); \
 
430
    } else { \
 
431
        nlw = (w) >> 2; \
 
432
    }
 
433
 
 
434
#define getbits24(psrc, dst, index) {\
 
435
    register int idx; \
 
436
    switch(idx = ((index)&3)<<1){ \
 
437
        case 0: \
 
438
                dst = (*(psrc) &cfbmask[idx]); \
 
439
                break; \
 
440
        case 6: \
 
441
                dst = BitLeft((*(psrc) &cfbmask[idx]), cfb24Shift[idx]); \
 
442
                break; \
 
443
        default: \
 
444
                dst = BitLeft((*(psrc) &cfbmask[idx]), cfb24Shift[idx]) | \
 
445
                BitRight(((*((psrc)+1)) &cfbmask[idx+1]), cfb24Shift[idx+1]); \
 
446
        }; \
 
447
}
 
448
 
 
449
#define putbits24(src, w, pdst, planemask, index) {\
 
450
    register PixelGroup dstpixel; \
 
451
    register unsigned int idx; \
 
452
    switch(idx = ((index)&3)<<1){ \
 
453
        case 0: \
 
454
                dstpixel = (*(pdst) &cfbmask[idx]); \
 
455
                break; \
 
456
        case 6: \
 
457
                dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx]); \
 
458
                break; \
 
459
        default: \
 
460
                dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx])| \
 
461
                BitRight(((*((pdst)+1)) &cfbmask[idx+1]), cfb24Shift[idx+1]); \
 
462
        }; \
 
463
    dstpixel &= ~(planemask); \
 
464
    dstpixel |= (src & planemask); \
 
465
    *(pdst) &= cfbrmask[idx]; \
 
466
    switch(idx){ \
 
467
        case 0: \
 
468
                *(pdst) |=  (dstpixel & cfbmask[idx]); \
 
469
                break; \
 
470
        case 2: \
 
471
        case 4: \
 
472
                pdst++;idx++; \
 
473
                *(pdst) = ((*(pdst))  & cfbrmask[idx]) | \
 
474
                                (BitLeft(dstpixel, cfb24Shift[idx]) & cfbmask[idx]); \
 
475
                pdst--;idx--; \
 
476
        case 6: \
 
477
                *(pdst) |=  (BitRight(dstpixel, cfb24Shift[idx]) & cfbmask[idx]); \
 
478
                break; \
 
479
        }; \
 
480
}
 
481
 
 
482
#define putbitsrop24(src, x, pdst, planemask, rop) \
 
483
{ \
 
484
    register PixelGroup t1, dstpixel; \
 
485
    register unsigned int idx; \
 
486
    switch(idx = (x)<<1){ \
 
487
        case 0: \
 
488
                dstpixel = (*(pdst) &cfbmask[idx]); \
 
489
                break; \
 
490
        case 6: \
 
491
                dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx]); \
 
492
                break; \
 
493
        default: \
 
494
                dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx])| \
 
495
                BitRight(((*((pdst)+1)) &cfbmask[idx+1]), cfb24Shift[idx+1]); \
 
496
        }; \
 
497
    DoRop(t1, rop, (src), dstpixel); \
 
498
    dstpixel &= ~planemask; \
 
499
    dstpixel |= (t1 & planemask); \
 
500
    *(pdst) &= cfbrmask[idx]; \
 
501
    switch(idx){ \
 
502
        case 0: \
 
503
                *(pdst) |= (dstpixel & cfbmask[idx]); \
 
504
                break; \
 
505
        case 2: \
 
506
        case 4: \
 
507
                *((pdst)+1) = ((*((pdst)+1))  & cfbrmask[idx+1]) | \
 
508
                                (BitLeft(dstpixel, cfb24Shift[idx+1]) & (cfbmask[idx+1])); \
 
509
        case 6: \
 
510
                *(pdst) |= (BitRight(dstpixel, cfb24Shift[idx]) & cfbmask[idx]); \
 
511
        }; \
 
512
}
 
513
# else  /* PSZ == 24 && PPW == 1 */
 
514
#define maskbits(x, w, startmask, endmask, nlw) \
 
515
    startmask = cfbstarttab[(x)&PIM]; \
 
516
    endmask = cfbendtab[((x)+(w)) & PIM]; \
 
517
    if (startmask) \
 
518
        nlw = (((w) - (PPW - ((x)&PIM))) >> PWSH); \
 
519
    else \
 
520
        nlw = (w) >> PWSH;
 
521
 
 
522
#define maskpartialbits(x, w, mask) \
 
523
    mask = cfbstartpartial[(x) & PIM] & cfbendpartial[((x) + (w)) & PIM];
 
524
 
 
525
#define mask32bits(x, w, startmask, endmask) \
 
526
    startmask = cfbstarttab[(x)&PIM]; \
 
527
    endmask = cfbendtab[((x)+(w)) & PIM];
 
528
 
 
529
/* FIXME */
 
530
#define maskbits24(x, w, startmask, endmask, nlw) \
 
531
    abort()
 
532
#define getbits24(psrc, dst, index) \
 
533
    abort()
 
534
#define putbits24(src, w, pdst, planemask, index) \
 
535
    abort()
 
536
#define putbitsrop24(src, x, pdst, planemask, rop) \
 
537
    abort()
 
538
 
 
539
#endif /* PSZ == 24 && PPW == 1 */
 
540
 
 
541
#define getbits(psrc, x, w, dst) \
 
542
if ( ((x) + (w)) <= PPW) \
 
543
{ \
 
544
    dst = SCRLEFT(*(psrc), (x)); \
 
545
} \
 
546
else \
 
547
{ \
 
548
    int m; \
 
549
    m = PPW-(x); \
 
550
    dst = (SCRLEFT(*(psrc), (x)) & cfbendtab[m]) | \
 
551
          (SCRRIGHT(*((psrc)+1), m) & cfbstarttab[m]); \
 
552
}
 
553
 
 
554
 
 
555
#define putbits(src, x, w, pdst, planemask) \
 
556
if ( ((x)+(w)) <= PPW) \
 
557
{ \
 
558
    PixelGroup tmpmask; \
 
559
    maskpartialbits((x), (w), tmpmask); \
 
560
    tmpmask &= PFILL(planemask); \
 
561
    *(pdst) = (*(pdst) & ~tmpmask) | (SCRRIGHT(src, x) & tmpmask); \
 
562
} \
 
563
else \
 
564
{ \
 
565
    unsigned int m; \
 
566
    unsigned int n; \
 
567
    PixelGroup pm = PFILL(planemask); \
 
568
    m = PPW-(x); \
 
569
    n = (w) - m; \
 
570
    *(pdst) = (*(pdst) & (cfbendtab[x] | ~pm)) | \
 
571
        (SCRRIGHT(src, x) & (cfbstarttab[x] & pm)); \
 
572
    *((pdst)+1) = (*((pdst)+1) & (cfbstarttab[n] | ~pm)) | \
 
573
        (SCRLEFT(src, m) & (cfbendtab[n] & pm)); \
 
574
}
 
575
#if defined(__GNUC__) && defined(mc68020)
 
576
#undef getbits
 
577
#define FASTGETBITS(psrc, x, w, dst) \
 
578
    asm ("bfextu %3{%1:%2},%0" \
 
579
         : "=d" (dst) : "di" (x), "di" (w), "o" (*(char *)(psrc)))
 
580
 
 
581
#define getbits(psrc,x,w,dst) \
 
582
{ \
 
583
    FASTGETBITS(psrc, (x) * PSZ, (w) * PSZ, dst); \
 
584
    dst = SCRLEFT(dst,PPW-(w)); \
 
585
}
 
586
 
 
587
#define FASTPUTBITS(src, x, w, pdst) \
 
588
    asm ("bfins %3,%0{%1:%2}" \
 
589
         : "=o" (*(char *)(pdst)) \
 
590
         : "di" (x), "di" (w), "d" (src), "0" (*(char *) (pdst)))
 
591
 
 
592
#undef putbits
 
593
#define putbits(src, x, w, pdst, planemask) \
 
594
{ \
 
595
    if (planemask != PMSK) { \
 
596
        PixelGroup _m, _pm; \
 
597
        FASTGETBITS(pdst, (x) * PSZ , (w) * PSZ, _m); \
 
598
        PFILL2(planemask, _pm); \
 
599
        _m &= (~_pm); \
 
600
        _m |= (SCRRIGHT(src, PPW-(w)) & _pm); \
 
601
        FASTPUTBITS(_m, (x) * PSZ, (w) * PSZ, pdst); \
 
602
    } else { \
 
603
        FASTPUTBITS(SCRRIGHT(src, PPW-(w)), (x) * PSZ, (w) * PSZ, pdst); \
 
604
    } \
 
605
}
 
606
    
 
607
 
 
608
#endif /* mc68020 */
 
609
 
 
610
#define putbitsrop(src, x, w, pdst, planemask, rop) \
 
611
if ( ((x)+(w)) <= PPW) \
 
612
{ \
 
613
    PixelGroup tmpmask; \
 
614
    PixelGroup t1, t2; \
 
615
    maskpartialbits((x), (w), tmpmask); \
 
616
    PFILL2(planemask, t1); \
 
617
    tmpmask &= t1; \
 
618
    t1 = SCRRIGHT((src), (x)); \
 
619
    DoRop(t2, rop, t1, *(pdst)); \
 
620
    *(pdst) = (*(pdst) & ~tmpmask) | (t2 & tmpmask); \
 
621
} \
 
622
else \
 
623
{ \
 
624
    CfbBits m; \
 
625
    CfbBits n; \
 
626
    PixelGroup t1, t2; \
 
627
    PixelGroup pm; \
 
628
    PFILL2(planemask, pm); \
 
629
    m = PPW-(x); \
 
630
    n = (w) - m; \
 
631
    t1 = SCRRIGHT((src), (x)); \
 
632
    DoRop(t2, rop, t1, *(pdst)); \
 
633
    *(pdst) = (*(pdst) & (cfbendtab[x] | ~pm)) | (t2 & (cfbstarttab[x] & pm));\
 
634
    t1 = SCRLEFT((src), m); \
 
635
    DoRop(t2, rop, t1, *((pdst) + 1)); \
 
636
    *((pdst)+1) = (*((pdst)+1) & (cfbstarttab[n] | ~pm)) | \
 
637
        (t2 & (cfbendtab[n] & pm)); \
 
638
}
 
639
 
 
640
#else /* PSZ == 32 && PPW == 1*/
 
641
 
 
642
/*
 
643
 * These macros can be optimized for 32-bit pixels since there is no
 
644
 * need to worry about left/right edge masking.  These macros were
 
645
 * derived from the above using the following reductions:
 
646
 *
 
647
 *      - x & PIW = 0   [since PIW = 0]
 
648
 *      - all masking tables are only indexed by 0  [ due to above ]
 
649
 *      - cfbstartab[0] and cfbendtab[0] = 0    [ no left/right edge masks]
 
650
 *    - cfbstartpartial[0] and cfbendpartial[0] = ~0 [no partial pixel mask]
 
651
 *
 
652
 * Macro reduction based upon constants cannot be performed automatically
 
653
 *       by the compiler since it does not know the contents of the masking
 
654
 *       arrays in cfbmskbits.c.
 
655
 */
 
656
#define maskbits(x, w, startmask, endmask, nlw) \
 
657
    startmask = endmask = 0; \
 
658
    nlw = (w);
 
659
 
 
660
#define maskpartialbits(x, w, mask) \
 
661
    mask = 0xFFFFFFFF;
 
662
 
 
663
#define mask32bits(x, w, startmask, endmask) \
 
664
    startmask = endmask = 0;
 
665
 
 
666
/*
 
667
 * For 32-bit operations, getbits(), putbits(), and putbitsrop() 
 
668
 * will only be invoked with x = 0 and w = PPW (1).  The getbits() 
 
669
 * macro is only called within left/right edge logic, which doesn't
 
670
 * happen for 32-bit pixels.
 
671
 */
 
672
#define getbits(psrc, x, w, dst) (dst) = *(psrc)
 
673
 
 
674
#define putbits(src, x, w, pdst, planemask) \
 
675
    *(pdst) = (*(pdst) & ~planemask) | (src & planemask);
 
676
 
 
677
#define putbitsrop(src, x, w, pdst, planemask, rop) \
 
678
{ \
 
679
    PixelGroup t1; \
 
680
    DoRop(t1, rop, (src), *(pdst)); \
 
681
    *(pdst) = (*(pdst) & ~planemask) | (t1 & planemask); \
 
682
}
 
683
 
 
684
#endif /* PSZ != 32 */
 
685
 
 
686
/*
 
687
 * Use these macros only when you're using the MergeRop stuff
 
688
 * in ../mfb/mergerop.h
 
689
 */
 
690
 
 
691
/* useful only when not spanning destination longwords */
 
692
#if PSZ == 24
 
693
#define putbitsmropshort24(src,x,w,pdst,index) {\
 
694
    PixelGroup   _tmpmask; \
 
695
    PixelGroup   _t1; \
 
696
    maskpartialbits ((x), (w), _tmpmask); \
 
697
    _t1 = SCRRIGHT((src), (x)); \
 
698
    DoMaskMergeRop24(_t1, pdst, _tmpmask, index); \
 
699
}
 
700
#endif
 
701
#define putbitsmropshort(src,x,w,pdst) {\
 
702
    PixelGroup   _tmpmask; \
 
703
    PixelGroup   _t1; \
 
704
    maskpartialbits ((x), (w), _tmpmask); \
 
705
    _t1 = SCRRIGHT((src), (x)); \
 
706
    *pdst = DoMaskMergeRop(_t1, *pdst, _tmpmask); \
 
707
}
 
708
 
 
709
/* useful only when spanning destination longwords */
 
710
#define putbitsmroplong(src,x,w,pdst) { \
 
711
    PixelGroup   _startmask, _endmask; \
 
712
    int             _m; \
 
713
    PixelGroup   _t1; \
 
714
    _m = PPW - (x); \
 
715
    _startmask = cfbstarttab[x]; \
 
716
    _endmask = cfbendtab[(w) - _m]; \
 
717
    _t1 = SCRRIGHT((src), (x)); \
 
718
    pdst[0] = DoMaskMergeRop(_t1,pdst[0],_startmask); \
 
719
    _t1 = SCRLEFT ((src),_m); \
 
720
    pdst[1] = DoMaskMergeRop(_t1,pdst[1],_endmask); \
 
721
}
 
722
 
 
723
#define putbitsmrop(src,x,w,pdst) \
 
724
if ((x) + (w) <= PPW) {\
 
725
    putbitsmropshort(src,x,w,pdst); \
 
726
} else { \
 
727
    putbitsmroplong(src,x,w,pdst); \
 
728
}
 
729
 
 
730
#if GETLEFTBITS_ALIGNMENT == 1
 
731
#define getleftbits(psrc, w, dst)       dst = *((unsigned int *) psrc)
 
732
#define getleftbits24(psrc, w, dst, idx){       \
 
733
        regiseter int index; \
 
734
        switch(index = ((idx)&3)<<1){ \
 
735
        case 0: \
 
736
        dst = (*((unsigned int *) psrc))&cfbmask[index]; \
 
737
        break; \
 
738
        case 2: \
 
739
        case 4: \
 
740
        dst = BitLeft(((*((unsigned int *) psrc))&cfbmask[index]), cfb24Shift[index]); \
 
741
        dst |= BitRight(((*((unsigned int *) psrc)+1)&cfbmask[index]), cfb4Shift[index]); \
 
742
        break; \
 
743
        case 6: \
 
744
        dst = BitLeft((*((unsigned int *) psrc)),cfb24Shift[index]); \
 
745
        break; \
 
746
        }; \
 
747
}
 
748
#endif /* GETLEFTBITS_ALIGNMENT == 1 */
 
749
 
 
750
#define getglyphbits(psrc, x, w, dst) \
 
751
{ \
 
752
    dst = BitLeft((unsigned) *(psrc), (x)); \
 
753
    if ( ((x) + (w)) > 32) \
 
754
        dst |= (BitRight((unsigned) *((psrc)+1), 32-(x))); \
 
755
}
 
756
#if GETLEFTBITS_ALIGNMENT == 2
 
757
#define getleftbits(psrc, w, dst) \
 
758
    { \
 
759
        if ( ((int)(psrc)) & 0x01 ) \
 
760
                getglyphbits( ((unsigned int *)(((char *)(psrc))-1)), 8, (w), (dst) ); \
 
761
        else \
 
762
                dst = *((unsigned int *) psrc); \
 
763
    }
 
764
#endif /* GETLEFTBITS_ALIGNMENT == 2 */
 
765
 
 
766
#if GETLEFTBITS_ALIGNMENT == 4
 
767
#define getleftbits(psrc, w, dst) \
 
768
    { \
 
769
        int off, off_b; \
 
770
        off_b = (off = ( ((int)(psrc)) & 0x03)) << 3; \
 
771
        getglyphbits( \
 
772
                (unsigned int *)( ((char *)(psrc)) - off), \
 
773
                (off_b), (w), (dst) \
 
774
               ); \
 
775
    }
 
776
#endif /* GETLEFTBITS_ALIGNMENT == 4 */
 
777
 
 
778
/*
 
779
 * getstipplepixels( psrcstip, x, w, ones, psrcpix, destpix )
 
780
 *
 
781
 * Converts bits to pixels in a reasonable way.  Takes w (1 <= w <= PPW)
 
782
 * bits from *psrcstip, starting at bit x; call this a quartet of bits.
 
783
 * Then, takes the pixels from *psrcpix corresponding to the one-bits (if
 
784
 * ones is TRUE) or the zero-bits (if ones is FALSE) of the quartet
 
785
 * and puts these pixels into destpix.
 
786
 *
 
787
 * Example:
 
788
 *
 
789
 *      getstipplepixels( &(0x08192A3B), 17, 4, 1, &(0x4C5D6E7F), dest )
 
790
 *
 
791
 * 0x08192A3B = 0000 1000 0001 1001 0010 1010 0011 1011
 
792
 *
 
793
 * This will take 4 bits starting at bit 17, so the quartet is 0x5 = 0101.
 
794
 * It will take pixels from 0x4C5D6E7F corresponding to the one-bits in this
 
795
 * quartet, so dest = 0x005D007F.
 
796
 *
 
797
 * XXX Works with both byte order.
 
798
 * XXX This works for all values of x and w within a doubleword.
 
799
 */
 
800
#if (BITMAP_BIT_ORDER == MSBFirst)
 
801
#define getstipplepixels( psrcstip, x, w, ones, psrcpix, destpix ) \
 
802
{ \
 
803
    PixelGroup q; \
 
804
    int m; \
 
805
    if ((m = ((x) - ((PPW*PSZ)-PPW))) > 0) { \
 
806
        q = (*(psrcstip)) << m; \
 
807
        if ( (x)+(w) > (PPW*PSZ) ) \
 
808
            q |= *((psrcstip)+1) >> ((PPW*PSZ)-m); \
 
809
    } \
 
810
    else \
 
811
        q = (*(psrcstip)) >> -m; \
 
812
    q = QuartetBitsTable[(w)] & ((ones) ? q : ~q); \
 
813
    *(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
 
814
}
 
815
/* I just copied this to get the linker satisfied on PowerPC,
 
816
 * so this may not be correct at all.
 
817
 */
 
818
#define getstipplepixels24(psrcstip,xt,ones,psrcpix,destpix,stipindex) \
 
819
{ \
 
820
    PixelGroup q; \
 
821
    q = *(psrcstip) >> (xt); \
 
822
    q = ((ones) ? q : ~q) & 1; \
 
823
    *(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
 
824
}
 
825
#else /* BITMAP_BIT_ORDER == LSB */
 
826
 
 
827
/* this must load 32 bits worth; for most machines, thats an int */
 
828
#define CfbFetchUnaligned(x)    ldl_u(x)
 
829
 
 
830
#define getstipplepixels( psrcstip, xt, w, ones, psrcpix, destpix ) \
 
831
{ \
 
832
    PixelGroup q; \
 
833
    q = CfbFetchUnaligned(psrcstip) >> (xt); \
 
834
    if ( ((xt)+(w)) > (PPW*PSZ) ) \
 
835
        q |= (CfbFetchUnaligned((psrcstip)+1)) << ((PPW*PSZ)-(xt)); \
 
836
    q = QuartetBitsTable[(w)] & ((ones) ? q : ~q); \
 
837
    *(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
 
838
}
 
839
#if PSZ == 24
 
840
# if 0
 
841
#define getstipplepixels24(psrcstip,xt,w,ones,psrcpix,destpix,stipindex,srcindex,dstindex) \
 
842
{ \
 
843
    PixelGroup q; \
 
844
    CfbBits src; \
 
845
    register unsigned int sidx; \
 
846
    register unsigned int didx; \
 
847
    sidx = ((srcindex) & 3)<<1; \
 
848
    didx = ((dstindex) & 3)<<1; \
 
849
    q = *(psrcstip) >> (xt); \
 
850
/*    if((srcindex)!=0)*/ \
 
851
/*    src = (((*(psrcpix)) << cfb24Shift[sidx]) & (cfbmask[sidx])) |*/ \
 
852
/*      (((*((psrcpix)+1)) << cfb24Shift[sidx+1]) & (cfbmask[sidx+1])); */\
 
853
/*    else */\
 
854
        src = (*(psrcpix))&0xFFFFFF; \
 
855
    if ( ((xt)+(w)) > PGSZ ) \
 
856
        q |= (*((psrcstip)+1)) << (PGSZ -(xt)); \
 
857
    q = QuartetBitsTable[(w)] & ((ones) ? q : ~q); \
 
858
    src &= QuartetPixelMaskTable[q]; \
 
859
    *(destpix) &= cfbrmask[didx]; \
 
860
    switch(didx) {\
 
861
        case 0: \
 
862
                *(destpix) |= (src &cfbmask[didx]); \
 
863
                break; \
 
864
        case 2: \
 
865
        case 4: \
 
866
                destpix++;didx++; \
 
867
                *(destpix) = ((*(destpix)) & (cfbrmask[didx]))| \
 
868
                        (BitLeft(src, cfb24Shift[didx]) & (cfbmask[didx])); \
 
869
                destpix--; didx--;\
 
870
        case 6: \
 
871
                *(destpix) |= (BitRight(src, cfb24Shift[didx]) & cfbmask[didx]); \
 
872
                break; \
 
873
        }; \
 
874
}
 
875
# else
 
876
#define getstipplepixels24(psrcstip,xt,ones,psrcpix,destpix,stipindex) \
 
877
{ \
 
878
    PixelGroup q; \
 
879
    q = *(psrcstip) >> (xt); \
 
880
    q = ((ones) ? q : ~q) & 1; \
 
881
    *(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
 
882
}
 
883
# endif
 
884
#endif /* PSZ == 24 */
 
885
#endif
 
886
 
 
887
extern PixelGroup cfbstarttab[];
 
888
extern PixelGroup cfbendtab[];
 
889
extern PixelGroup cfbstartpartial[];
 
890
extern PixelGroup cfbendpartial[];
 
891
extern PixelGroup cfbrmask[];
 
892
extern PixelGroup cfbmask[];
 
893
extern PixelGroup QuartetBitsTable[];
 
894
extern PixelGroup QuartetPixelMaskTable[];
 
895
#if PSZ == 24
 
896
extern int cfb24Shift[];
 
897
#endif