VirtualBox

source: vbox/trunk/src/VBox/Additions/x11/x11include/xorg-server-1.4.2/cfbmskbits.h@ 68495

Last change on this file since 68495 was 43272, checked in by vboxsync, 12 years ago

Additions/x11: more original X server headers.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette