VirtualBox

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

最後變更 在這個檔案從25078是 25078,由 vboxsync 提交於 15 年 前

Additions/x11/x11include: exported and set eol-style on new headers

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

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