1 | /* $XFree86: xc/programs/Xserver/mfb/maskbits.h,v 3.8tsi Exp $ */
|
---|
2 | /* Combined Purdue/PurduePlus patches, level 2.1, 1/24/89 */
|
---|
3 | /***********************************************************
|
---|
4 | Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
---|
5 |
|
---|
6 | All Rights Reserved
|
---|
7 |
|
---|
8 | Permission to use, copy, modify, and distribute this software and its
|
---|
9 | documentation for any purpose and without fee is hereby granted,
|
---|
10 | provided that the above copyright notice appear in all copies and that
|
---|
11 | both that copyright notice and this permission notice appear in
|
---|
12 | supporting documentation, and that the name of Digital not be
|
---|
13 | used in advertising or publicity pertaining to distribution of the
|
---|
14 | software without specific, written prior permission.
|
---|
15 |
|
---|
16 | DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
---|
17 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
---|
18 | DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
---|
19 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
---|
20 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
---|
21 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
---|
22 | SOFTWARE.
|
---|
23 |
|
---|
24 | ******************************************************************/
|
---|
25 | /* $Xorg: maskbits.h,v 1.3 2000/08/17 19:53:34 cpqbld Exp $ */
|
---|
26 |
|
---|
27 | #ifdef HAVE_DIX_CONFIG_H
|
---|
28 | #include <dix-config.h>
|
---|
29 | #endif
|
---|
30 |
|
---|
31 | #include <X11/X.h>
|
---|
32 | #include <X11/Xmd.h>
|
---|
33 | #include "servermd.h"
|
---|
34 |
|
---|
35 |
|
---|
36 | /* the following notes use the following conventions:
|
---|
37 | SCREEN LEFT SCREEN RIGHT
|
---|
38 | in this file and maskbits.c, left and right refer to screen coordinates,
|
---|
39 | NOT bit numbering in registers.
|
---|
40 |
|
---|
41 | starttab[n]
|
---|
42 | bits[0,n-1] = 0 bits[n,PLST] = 1
|
---|
43 | endtab[n] =
|
---|
44 | bits[0,n-1] = 1 bits[n,PLST] = 0
|
---|
45 |
|
---|
46 | startpartial[], endpartial[]
|
---|
47 | these are used as accelerators for doing putbits and masking out
|
---|
48 | bits that are all contained between longword boudaries. the extra
|
---|
49 | 256 bytes of data seems a small price to pay -- code is smaller,
|
---|
50 | and narrow things (e.g. window borders) go faster.
|
---|
51 |
|
---|
52 | the names may seem misleading; they are derived not from which end
|
---|
53 | of the word the bits are turned on, but at which end of a scanline
|
---|
54 | the table tends to be used.
|
---|
55 |
|
---|
56 | look at the tables and macros to understand boundary conditions.
|
---|
57 | (careful readers will note that starttab[n] = ~endtab[n] for n != 0)
|
---|
58 |
|
---|
59 | -----------------------------------------------------------------------
|
---|
60 | these two macros depend on the screen's bit ordering.
|
---|
61 | in both of them x is a screen position. they are used to
|
---|
62 | combine bits collected from multiple longwords into a
|
---|
63 | single destination longword, and to unpack a single
|
---|
64 | source longword into multiple destinations.
|
---|
65 |
|
---|
66 | SCRLEFT(dst, x)
|
---|
67 | takes dst[x, PPW] and moves them to dst[0, PPW-x]
|
---|
68 | the contents of the rest of dst are 0.
|
---|
69 | this is a right shift on LSBFirst (forward-thinking)
|
---|
70 | machines like the VAX, and left shift on MSBFirst
|
---|
71 | (backwards) machines like the 680x0 and pc/rt.
|
---|
72 |
|
---|
73 | SCRRIGHT(dst, x)
|
---|
74 | takes dst[0,x] and moves them to dst[PPW-x, PPW]
|
---|
75 | the contents of the rest of dst are 0.
|
---|
76 | this is a left shift on LSBFirst, right shift
|
---|
77 | on MSBFirst.
|
---|
78 |
|
---|
79 |
|
---|
80 | the remaining macros are cpu-independent; all bit order dependencies
|
---|
81 | are built into the tables and the two macros above.
|
---|
82 |
|
---|
83 | maskbits(x, w, startmask, endmask, nlw)
|
---|
84 | for a span of width w starting at position x, returns
|
---|
85 | a mask for ragged bits at start, mask for ragged bits at end,
|
---|
86 | and the number of whole longwords between the ends.
|
---|
87 |
|
---|
88 | maskpartialbits(x, w, mask)
|
---|
89 | works like maskbits(), except all the bits are in the
|
---|
90 | same longword (i.e. (x&PIM + w) <= PPW)
|
---|
91 |
|
---|
92 | maskPPWbits(x, w, startmask, endmask, nlw)
|
---|
93 | as maskbits, but does not calculate nlw. it is used by
|
---|
94 | mfbGlyphBlt to put down glyphs <= PPW bits wide.
|
---|
95 |
|
---|
96 | -------------------------------------------------------------------
|
---|
97 |
|
---|
98 | NOTE
|
---|
99 | any pointers passed to the following 4 macros are
|
---|
100 | guranteed to be PPW-bit aligned.
|
---|
101 | The only non-PPW-bit-aligned references ever made are
|
---|
102 | to font glyphs, and those are made with getleftbits()
|
---|
103 | and getshiftedleftbits (qq.v.)
|
---|
104 |
|
---|
105 | For 64-bit server, it is assumed that we will never have font padding
|
---|
106 | of more than 4 bytes. The code uses int's to access the fonts
|
---|
107 | intead of longs.
|
---|
108 |
|
---|
109 | getbits(psrc, x, w, dst)
|
---|
110 | starting at position x in psrc (x < PPW), collect w
|
---|
111 | bits and put them in the screen left portion of dst.
|
---|
112 | psrc is a longword pointer. this may span longword boundaries.
|
---|
113 | it special-cases fetching all w bits from one longword.
|
---|
114 |
|
---|
115 | +--------+--------+ +--------+
|
---|
116 | | | m |n| | ==> | m |n| |
|
---|
117 | +--------+--------+ +--------+
|
---|
118 | x x+w 0 w
|
---|
119 | psrc psrc+1 dst
|
---|
120 | m = PPW - x
|
---|
121 | n = w - m
|
---|
122 |
|
---|
123 | implementation:
|
---|
124 | get m bits, move to screen-left of dst, zeroing rest of dst;
|
---|
125 | get n bits from next word, move screen-right by m, zeroing
|
---|
126 | lower m bits of word.
|
---|
127 | OR the two things together.
|
---|
128 |
|
---|
129 | putbits(src, x, w, pdst)
|
---|
130 | starting at position x in pdst, put down the screen-leftmost
|
---|
131 | w bits of src. pdst is a longword pointer. this may
|
---|
132 | span longword boundaries.
|
---|
133 | it special-cases putting all w bits into the same longword.
|
---|
134 |
|
---|
135 | +--------+ +--------+--------+
|
---|
136 | | m |n| | ==> | | m |n| |
|
---|
137 | +--------+ +--------+--------+
|
---|
138 | 0 w x x+w
|
---|
139 | dst pdst pdst+1
|
---|
140 | m = PPW - x
|
---|
141 | n = w - m
|
---|
142 |
|
---|
143 | implementation:
|
---|
144 | get m bits, shift screen-right by x, zero screen-leftmost x
|
---|
145 | bits; zero rightmost m bits of *pdst and OR in stuff
|
---|
146 | from before the semicolon.
|
---|
147 | shift src screen-left by m, zero bits n-PPW;
|
---|
148 | zero leftmost n bits of *(pdst+1) and OR in the
|
---|
149 | stuff from before the semicolon.
|
---|
150 |
|
---|
151 | putbitsrop(src, x, w, pdst, ROP)
|
---|
152 | like putbits but calls DoRop with the rasterop ROP (see mfb.h for
|
---|
153 | DoRop)
|
---|
154 |
|
---|
155 | putbitsrrop(src, x, w, pdst, ROP)
|
---|
156 | like putbits but calls DoRRop with the reduced rasterop ROP
|
---|
157 | (see mfb.h for DoRRop)
|
---|
158 |
|
---|
159 | -----------------------------------------------------------------------
|
---|
160 | The two macros below are used only for getting bits from glyphs
|
---|
161 | in fonts, and glyphs in fonts are gotten only with the following two
|
---|
162 | mcros.
|
---|
163 | You should tune these macros toyour font format and cpu
|
---|
164 | byte ordering.
|
---|
165 |
|
---|
166 | NOTE
|
---|
167 | getleftbits(psrc, w, dst)
|
---|
168 | get the leftmost w (w<=32) bits from *psrc and put them
|
---|
169 | in dst. this is used by the mfbGlyphBlt code for glyphs
|
---|
170 | <=PPW bits wide.
|
---|
171 | psrc is declared (unsigned char *)
|
---|
172 |
|
---|
173 | psrc is NOT guaranteed to be PPW-bit aligned. on many
|
---|
174 | machines this will cause problems, so there are several
|
---|
175 | versions of this macro.
|
---|
176 |
|
---|
177 | this macro is called ONLY for getting bits from font glyphs,
|
---|
178 | and depends on the server-natural font padding.
|
---|
179 |
|
---|
180 | for blazing text performance, you want this macro
|
---|
181 | to touch memory as infrequently as possible (e.g.
|
---|
182 | fetch longwords) and as efficiently as possible
|
---|
183 | (e.g. don't fetch misaligned longwords)
|
---|
184 |
|
---|
185 | getshiftedleftbits(psrc, offset, w, dst)
|
---|
186 | used by the font code; like getleftbits, but shifts the
|
---|
187 | bits SCRLEFT by offset.
|
---|
188 | this is implemented portably, calling getleftbits()
|
---|
189 | and SCRLEFT().
|
---|
190 | psrc is declared (unsigned char *).
|
---|
191 | */
|
---|
192 |
|
---|
193 | /* to match CFB and allow algorithm sharing ...
|
---|
194 | * name mfb32 mfb64 explanation
|
---|
195 | * ---- ------ ----- -----------
|
---|
196 | * PGSZ 32 64 pixel group size (in bits; same as PPW for mfb)
|
---|
197 | * PGSZB 4 8 pixel group size (in bytes)
|
---|
198 | * PPW 32 64 pixels per word (pixels per pixel group)
|
---|
199 | * PLST 31 63 index of last pixel in a word (should be PPW-1)
|
---|
200 | * PIM 0x1f 0x3f pixel index mask (index within a pixel group)
|
---|
201 | * PWSH 5 6 pixel-to-word shift (should be log2(PPW))
|
---|
202 | *
|
---|
203 | * The MFB_ versions are here so that cfb can include maskbits.h to get
|
---|
204 | * the bitmap constants without conflicting with its own P* constants.
|
---|
205 | *
|
---|
206 | * Keith Packard ([email protected]):
|
---|
207 | * Note mfb64 is no longer supported; it requires DIX support
|
---|
208 | * for realigning images which costs too much
|
---|
209 | */
|
---|
210 |
|
---|
211 | /* warning: PixelType definition duplicated in mfb.h */
|
---|
212 | #ifndef PixelType
|
---|
213 | #define PixelType CARD32
|
---|
214 | #endif /* PixelType */
|
---|
215 | #ifndef MfbBits
|
---|
216 | #define MfbBits CARD32
|
---|
217 | #endif
|
---|
218 |
|
---|
219 | #define MFB_PGSZB 4
|
---|
220 | #define MFB_PPW (MFB_PGSZB<<3) /* assuming 8 bits per byte */
|
---|
221 | #define MFB_PGSZ MFB_PPW
|
---|
222 | #define MFB_PLST (MFB_PPW-1)
|
---|
223 | #define MFB_PIM MFB_PLST
|
---|
224 |
|
---|
225 | /* set PWSH = log2(PPW) using brute force */
|
---|
226 |
|
---|
227 | #if MFB_PPW == 32
|
---|
228 | #define MFB_PWSH 5
|
---|
229 | #endif /* MFB_PPW == 32 */
|
---|
230 |
|
---|
231 | /* XXX don't use these five */
|
---|
232 | extern PixelType starttab[];
|
---|
233 | extern PixelType endtab[];
|
---|
234 | extern PixelType partmasks[MFB_PPW][MFB_PPW];
|
---|
235 | extern PixelType rmask[];
|
---|
236 | extern PixelType mask[];
|
---|
237 | /* XXX use these five */
|
---|
238 | extern PixelType mfbGetstarttab(int);
|
---|
239 | extern PixelType mfbGetendtab(int);
|
---|
240 | extern PixelType mfbGetpartmasks(int, int);
|
---|
241 | extern PixelType mfbGetrmask(int);
|
---|
242 | extern PixelType mfbGetmask(int);
|
---|
243 |
|
---|
244 | #ifndef MFB_CONSTS_ONLY
|
---|
245 |
|
---|
246 | #define PGSZB MFB_PGSZB
|
---|
247 | #define PPW MFB_PPW
|
---|
248 | #define PGSZ MFB_PGSZ
|
---|
249 | #define PLST MFB_PLST
|
---|
250 | #define PIM MFB_PIM
|
---|
251 | #define PWSH MFB_PWSH
|
---|
252 |
|
---|
253 | #define BitLeft(b,s) SCRLEFT(b,s)
|
---|
254 | #define BitRight(b,s) SCRRIGHT(b,s)
|
---|
255 |
|
---|
256 | #ifdef XFree86Server
|
---|
257 | #define LONG2CHARSSAMEORDER(x) ((MfbBits)(x))
|
---|
258 | #define LONG2CHARSDIFFORDER( x ) ( ( ( ( x ) & (MfbBits)0x000000FF ) << 0x18 ) \
|
---|
259 | | ( ( ( x ) & (MfbBits)0x0000FF00 ) << 0x08 ) \
|
---|
260 | | ( ( ( x ) & (MfbBits)0x00FF0000 ) >> 0x08 ) \
|
---|
261 | | ( ( ( x ) & (MfbBits)0xFF000000 ) >> 0x18 ) )
|
---|
262 | #endif /* XFree86Server */
|
---|
263 |
|
---|
264 | #if (BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER)
|
---|
265 | #define LONG2CHARS(x) ((MfbBits)(x))
|
---|
266 | #else
|
---|
267 | /*
|
---|
268 | * the unsigned case below is for compilers like
|
---|
269 | * the Danbury C and i386cc
|
---|
270 | */
|
---|
271 | #define LONG2CHARS( x ) ( ( ( ( x ) & (MfbBits)0x000000FF ) << 0x18 ) \
|
---|
272 | | ( ( ( x ) & (MfbBits)0x0000FF00 ) << 0x08 ) \
|
---|
273 | | ( ( ( x ) & (MfbBits)0x00FF0000 ) >> 0x08 ) \
|
---|
274 | | ( ( ( x ) & (MfbBits)0xFF000000 ) >> 0x18 ) )
|
---|
275 | #endif /* BITMAP_BIT_ORDER */
|
---|
276 |
|
---|
277 | #ifdef STRICT_ANSI_SHIFT
|
---|
278 | #define SHL(x,y) ((y) >= PPW ? 0 : LONG2CHARS(LONG2CHARS(x) << (y)))
|
---|
279 | #define SHR(x,y) ((y) >= PPW ? 0 : LONG2CHARS(LONG2CHARS(x) >> (y)))
|
---|
280 | #else
|
---|
281 | #define SHL(x,y) LONG2CHARS(LONG2CHARS(x) << (y))
|
---|
282 | #define SHR(x,y) LONG2CHARS(LONG2CHARS(x) >> (y))
|
---|
283 | #endif
|
---|
284 |
|
---|
285 | #if (BITMAP_BIT_ORDER == MSBFirst) /* pc/rt, 680x0 */
|
---|
286 | #define SCRLEFT(lw, n) SHL((PixelType)(lw),(n))
|
---|
287 | #define SCRRIGHT(lw, n) SHR((PixelType)(lw),(n))
|
---|
288 | #else /* vax, intel */
|
---|
289 | #define SCRLEFT(lw, n) SHR((PixelType)(lw),(n))
|
---|
290 | #define SCRRIGHT(lw, n) SHL((PixelType)(lw),(n))
|
---|
291 | #endif
|
---|
292 |
|
---|
293 | #define DoRRop(alu, src, dst) \
|
---|
294 | (((alu) == RROP_BLACK) ? ((dst) & ~(src)) : \
|
---|
295 | ((alu) == RROP_WHITE) ? ((dst) | (src)) : \
|
---|
296 | ((alu) == RROP_INVERT) ? ((dst) ^ (src)) : \
|
---|
297 | (dst))
|
---|
298 |
|
---|
299 | /* A generalized form of a x4 Duff's Device */
|
---|
300 | #define Duff(counter, block) { \
|
---|
301 | while (counter >= 4) {\
|
---|
302 | { block; } \
|
---|
303 | { block; } \
|
---|
304 | { block; } \
|
---|
305 | { block; } \
|
---|
306 | counter -= 4; \
|
---|
307 | } \
|
---|
308 | switch (counter & 3) { \
|
---|
309 | case 3: { block; } \
|
---|
310 | case 2: { block; } \
|
---|
311 | case 1: { block; } \
|
---|
312 | case 0: \
|
---|
313 | counter = 0; \
|
---|
314 | } \
|
---|
315 | }
|
---|
316 |
|
---|
317 | #define maskbits(x, w, startmask, endmask, nlw) \
|
---|
318 | startmask = mfbGetstarttab((x) & PIM); \
|
---|
319 | endmask = mfbGetendtab(((x)+(w)) & PIM); \
|
---|
320 | if (startmask) \
|
---|
321 | nlw = (((w) - (PPW - ((x) & PIM))) >> PWSH); \
|
---|
322 | else \
|
---|
323 | nlw = (w) >> PWSH;
|
---|
324 |
|
---|
325 | #define maskpartialbits(x, w, mask) \
|
---|
326 | mask = mfbGetpartmasks((x) & PIM, (w) & PIM);
|
---|
327 |
|
---|
328 | #define maskPPWbits(x, w, startmask, endmask) \
|
---|
329 | startmask = mfbGetstarttab((x) & PIM); \
|
---|
330 | endmask = mfbGetendtab(((x)+(w)) & PIM);
|
---|
331 |
|
---|
332 | #ifdef __GNUC__ /* XXX don't want for Alpha? */
|
---|
333 | #ifdef vax
|
---|
334 | #define FASTGETBITS(psrc,x,w,dst) \
|
---|
335 | __asm ("extzv %1,%2,%3,%0" \
|
---|
336 | : "=g" (dst) \
|
---|
337 | : "g" (x), "g" (w), "m" (*(char *)(psrc)))
|
---|
338 | #define getbits(psrc,x,w,dst) FASTGETBITS(psrc,x,w,dst)
|
---|
339 |
|
---|
340 | #define FASTPUTBITS(src, x, w, pdst) \
|
---|
341 | __asm ("insv %3,%1,%2,%0" \
|
---|
342 | : "=m" (*(char *)(pdst)) \
|
---|
343 | : "g" (x), "g" (w), "g" (src))
|
---|
344 | #define putbits(src, x, w, pdst) FASTPUTBITS(src, x, w, pdst)
|
---|
345 | #endif /* vax */
|
---|
346 | #ifdef mc68020
|
---|
347 | #define FASTGETBITS(psrc, x, w, dst) \
|
---|
348 | __asm ("bfextu %3{%1:%2},%0" \
|
---|
349 | : "=d" (dst) : "di" (x), "di" (w), "o" (*(char *)(psrc)))
|
---|
350 |
|
---|
351 | #define getbits(psrc,x,w,dst) \
|
---|
352 | { \
|
---|
353 | FASTGETBITS(psrc, x, w, dst);\
|
---|
354 | dst = SHL(dst,(32-(w))); \
|
---|
355 | }
|
---|
356 |
|
---|
357 | #define FASTPUTBITS(src, x, w, pdst) \
|
---|
358 | __asm ("bfins %3,%0{%1:%2}" \
|
---|
359 | : "=o" (*(char *)(pdst)) \
|
---|
360 | : "di" (x), "di" (w), "d" (src), "0" (*(char *) (pdst)))
|
---|
361 |
|
---|
362 | #define putbits(src, x, w, pdst) FASTPUTBITS(SHR((src),32-(w)), x, w, pdst)
|
---|
363 |
|
---|
364 | #endif /* mc68020 */
|
---|
365 | #endif /* __GNUC__ */
|
---|
366 |
|
---|
367 | /* The following flag is used to override a bugfix for sun 3/60+CG4 machines,
|
---|
368 | */
|
---|
369 |
|
---|
370 | /* We don't need to be careful about this unless we're dealing with sun3's
|
---|
371 | * We will default its usage for those who do not know anything, but will
|
---|
372 | * override its effect if the machine doesn't look like a sun3
|
---|
373 | */
|
---|
374 | #if !defined(mc68020) || !defined(sun)
|
---|
375 | #define NO_3_60_CG4
|
---|
376 | #endif
|
---|
377 |
|
---|
378 | /* This is gross. We want to #define u_putbits as something which can be used
|
---|
379 | * in the case of the 3/60+CG4, but if we use /bin/cc or are on another
|
---|
380 | * machine type, we want nothing to do with u_putbits. What a hastle. Here
|
---|
381 | * I used slo_putbits as something which either u_putbits or putbits could be
|
---|
382 | * defined as.
|
---|
383 | *
|
---|
384 | * putbits gets it iff it is not already defined with FASTPUTBITS above.
|
---|
385 | * u_putbits gets it if we have FASTPUTBITS (putbits) from above and have not
|
---|
386 | * overridden the NO_3_60_CG4 flag.
|
---|
387 | */
|
---|
388 |
|
---|
389 | #define slo_putbits(src, x, w, pdst) \
|
---|
390 | { \
|
---|
391 | register int n = (x)+(w)-PPW; \
|
---|
392 | \
|
---|
393 | if (n <= 0) \
|
---|
394 | { \
|
---|
395 | register PixelType tmpmask; \
|
---|
396 | maskpartialbits((x), (w), tmpmask); \
|
---|
397 | *(pdst) = (*(pdst) & ~tmpmask) | \
|
---|
398 | (SCRRIGHT(src, x) & tmpmask); \
|
---|
399 | } \
|
---|
400 | else \
|
---|
401 | { \
|
---|
402 | register int d = PPW-(x); \
|
---|
403 | *(pdst) = (*(pdst) & mfbGetendtab(x)) | (SCRRIGHT((src), x)); \
|
---|
404 | (pdst)[1] = ((pdst)[1] & mfbGetstarttab(n)) | \
|
---|
405 | (SCRLEFT(src, d) & mfbGetendtab(n)); \
|
---|
406 | } \
|
---|
407 | }
|
---|
408 |
|
---|
409 | #if defined(putbits) && !defined(NO_3_60_CG4)
|
---|
410 | #define u_putbits(src, x, w, pdst) slo_putbits(src, x, w, pdst)
|
---|
411 | #else
|
---|
412 | #define u_putbits(src, x, w, pdst) putbits(src, x, w, pdst)
|
---|
413 | #endif
|
---|
414 |
|
---|
415 | #if !defined(putbits)
|
---|
416 | #define putbits(src, x, w, pdst) slo_putbits(src, x, w, pdst)
|
---|
417 | #endif
|
---|
418 |
|
---|
419 | /* Now if we have not gotten any really good bitfield macros, try some
|
---|
420 | * moderately fast macros. Alas, I don't know how to do asm instructions
|
---|
421 | * without gcc.
|
---|
422 | */
|
---|
423 |
|
---|
424 | #ifndef getbits
|
---|
425 | #define getbits(psrc, x, w, dst) \
|
---|
426 | { \
|
---|
427 | dst = SCRLEFT(*(psrc), (x)); \
|
---|
428 | if ( ((x) + (w)) > PPW) \
|
---|
429 | dst |= (SCRRIGHT(*((psrc)+1), PPW-(x))); \
|
---|
430 | }
|
---|
431 | #endif
|
---|
432 |
|
---|
433 | /* We have to special-case putbitsrop because of 3/60+CG4 combos
|
---|
434 | */
|
---|
435 |
|
---|
436 | #define u_putbitsrop(src, x, w, pdst, rop) \
|
---|
437 | {\
|
---|
438 | register PixelType t1, t2; \
|
---|
439 | register int n = (x)+(w)-PPW; \
|
---|
440 | \
|
---|
441 | t1 = SCRRIGHT((src), (x)); \
|
---|
442 | DoRop(t2, rop, t1, *(pdst)); \
|
---|
443 | \
|
---|
444 | if (n <= 0) \
|
---|
445 | { \
|
---|
446 | register PixelType tmpmask; \
|
---|
447 | \
|
---|
448 | maskpartialbits((x), (w), tmpmask); \
|
---|
449 | *(pdst) = (*(pdst) & ~tmpmask) | (t2 & tmpmask); \
|
---|
450 | } \
|
---|
451 | else \
|
---|
452 | { \
|
---|
453 | int m = PPW-(x); \
|
---|
454 | *(pdst) = (*(pdst) & mfbGetendtab(x)) | (t2 & mfbGetstarttab(x)); \
|
---|
455 | t1 = SCRLEFT((src), m); \
|
---|
456 | DoRop(t2, rop, t1, (pdst)[1]); \
|
---|
457 | (pdst)[1] = ((pdst)[1] & mfbGetstarttab(n)) | (t2 & mfbGetendtab(n)); \
|
---|
458 | } \
|
---|
459 | }
|
---|
460 |
|
---|
461 | /* If our getbits and putbits are FAST enough,
|
---|
462 | * do this brute force, it's faster
|
---|
463 | */
|
---|
464 |
|
---|
465 | #if defined(FASTPUTBITS) && defined(FASTGETBITS) && defined(NO_3_60_CG4)
|
---|
466 | #if (BITMAP_BIT_ORDER == MSBFirst)
|
---|
467 | #define putbitsrop(src, x, w, pdst, rop) \
|
---|
468 | { \
|
---|
469 | register PixelType _tmp, _tmp2; \
|
---|
470 | FASTGETBITS(pdst, x, w, _tmp); \
|
---|
471 | _tmp2 = SCRRIGHT(src, PPW-(w)); \
|
---|
472 | DoRop(_tmp, rop, _tmp2, _tmp) \
|
---|
473 | FASTPUTBITS(_tmp, x, w, pdst); \
|
---|
474 | }
|
---|
475 | #define putbitsrrop(src, x, w, pdst, rop) \
|
---|
476 | { \
|
---|
477 | register PixelType _tmp, _tmp2; \
|
---|
478 | \
|
---|
479 | FASTGETBITS(pdst, x, w, _tmp); \
|
---|
480 | _tmp2 = SCRRIGHT(src, PPW-(w)); \
|
---|
481 | _tmp= DoRRop(rop, _tmp2, _tmp); \
|
---|
482 | FASTPUTBITS(_tmp, x, w, pdst); \
|
---|
483 | }
|
---|
484 | #undef u_putbitsrop
|
---|
485 | #else
|
---|
486 | #define putbitsrop(src, x, w, pdst, rop) \
|
---|
487 | { \
|
---|
488 | register PixelType _tmp; \
|
---|
489 | FASTGETBITS(pdst, x, w, _tmp); \
|
---|
490 | DoRop(_tmp, rop, src, _tmp) \
|
---|
491 | FASTPUTBITS(_tmp, x, w, pdst); \
|
---|
492 | }
|
---|
493 | #define putbitsrrop(src, x, w, pdst, rop) \
|
---|
494 | { \
|
---|
495 | register PixelType _tmp; \
|
---|
496 | \
|
---|
497 | FASTGETBITS(pdst, x, w, _tmp); \
|
---|
498 | _tmp= DoRRop(rop, src, _tmp); \
|
---|
499 | FASTPUTBITS(_tmp, x, w, pdst); \
|
---|
500 | }
|
---|
501 | #undef u_putbitsrop
|
---|
502 | #endif
|
---|
503 | #endif
|
---|
504 |
|
---|
505 | #ifndef putbitsrop
|
---|
506 | #define putbitsrop(src, x, w, pdst, rop) u_putbitsrop(src, x, w, pdst, rop)
|
---|
507 | #endif
|
---|
508 |
|
---|
509 | #ifndef putbitsrrop
|
---|
510 | #define putbitsrrop(src, x, w, pdst, rop) \
|
---|
511 | {\
|
---|
512 | register PixelType t1, t2; \
|
---|
513 | register int n = (x)+(w)-PPW; \
|
---|
514 | \
|
---|
515 | t1 = SCRRIGHT((src), (x)); \
|
---|
516 | t2 = DoRRop(rop, t1, *(pdst)); \
|
---|
517 | \
|
---|
518 | if (n <= 0) \
|
---|
519 | { \
|
---|
520 | register PixelType tmpmask; \
|
---|
521 | \
|
---|
522 | maskpartialbits((x), (w), tmpmask); \
|
---|
523 | *(pdst) = (*(pdst) & ~tmpmask) | (t2 & tmpmask); \
|
---|
524 | } \
|
---|
525 | else \
|
---|
526 | { \
|
---|
527 | int m = PPW-(x); \
|
---|
528 | *(pdst) = (*(pdst) & mfbGetendtab(x)) | (t2 & mfbGetstarttab(x)); \
|
---|
529 | t1 = SCRLEFT((src), m); \
|
---|
530 | t2 = DoRRop(rop, t1, (pdst)[1]); \
|
---|
531 | (pdst)[1] = ((pdst)[1] & mfbGetstarttab(n)) | (t2 & mfbGetendtab(n)); \
|
---|
532 | } \
|
---|
533 | }
|
---|
534 | #endif
|
---|
535 |
|
---|
536 | #if GETLEFTBITS_ALIGNMENT == 1
|
---|
537 | #define getleftbits(psrc, w, dst) dst = *((CARD32 *)(pointer) psrc)
|
---|
538 | #endif /* GETLEFTBITS_ALIGNMENT == 1 */
|
---|
539 |
|
---|
540 | #if GETLEFTBITS_ALIGNMENT == 2
|
---|
541 | #define getleftbits(psrc, w, dst) \
|
---|
542 | { \
|
---|
543 | if ( ((int)(psrc)) & 0x01 ) \
|
---|
544 | getbits( ((CARD32 *)(((char *)(psrc))-1)), 8, (w), (dst) ); \
|
---|
545 | else \
|
---|
546 | getbits(psrc, 0, w, dst); \
|
---|
547 | }
|
---|
548 | #endif /* GETLEFTBITS_ALIGNMENT == 2 */
|
---|
549 |
|
---|
550 | #if GETLEFTBITS_ALIGNMENT == 4
|
---|
551 | #define getleftbits(psrc, w, dst) \
|
---|
552 | { \
|
---|
553 | int off, off_b; \
|
---|
554 | off_b = (off = ( ((int)(psrc)) & 0x03)) << 3; \
|
---|
555 | getbits( \
|
---|
556 | (CARD32 *)( ((char *)(psrc)) - off), \
|
---|
557 | (off_b), (w), (dst) \
|
---|
558 | ); \
|
---|
559 | }
|
---|
560 | #endif /* GETLEFTBITS_ALIGNMENT == 4 */
|
---|
561 |
|
---|
562 |
|
---|
563 | #define getshiftedleftbits(psrc, offset, w, dst) \
|
---|
564 | getleftbits((psrc), (w), (dst)); \
|
---|
565 | dst = SCRLEFT((dst), (offset));
|
---|
566 |
|
---|
567 | /* FASTGETBITS and FASTPUTBITS are not necessarily correct implementations of
|
---|
568 | * getbits and putbits, but they work if used together.
|
---|
569 | *
|
---|
570 | * On a MSBFirst machine, a cpu bitfield extract instruction (like bfextu)
|
---|
571 | * could normally assign its result to a 32-bit word register in the screen
|
---|
572 | * right position. This saves canceling register shifts by not fighting the
|
---|
573 | * natural cpu byte order.
|
---|
574 | *
|
---|
575 | * Unfortunately, these fail on a 3/60+CG4 and cannot be used unmodified. Sigh.
|
---|
576 | */
|
---|
577 | #if defined(FASTGETBITS) && defined(FASTPUTBITS)
|
---|
578 | #ifdef NO_3_60_CG4
|
---|
579 | #define u_FASTPUT(aa, bb, cc, dd) FASTPUTBITS(aa, bb, cc, dd)
|
---|
580 | #else
|
---|
581 | #define u_FASTPUT(aa, bb, cc, dd) u_putbits(SCRLEFT(aa, PPW-(cc)), bb, cc, dd)
|
---|
582 | #endif
|
---|
583 |
|
---|
584 | #define getandputbits(psrc, srcbit, dstbit, width, pdst) \
|
---|
585 | { \
|
---|
586 | register PixelType _tmpbits; \
|
---|
587 | FASTGETBITS(psrc, srcbit, width, _tmpbits); \
|
---|
588 | u_FASTPUT(_tmpbits, dstbit, width, pdst); \
|
---|
589 | }
|
---|
590 |
|
---|
591 | #define getandputrop(psrc, srcbit, dstbit, width, pdst, rop) \
|
---|
592 | { \
|
---|
593 | register PixelType _tmpsrc, _tmpdst; \
|
---|
594 | FASTGETBITS(pdst, dstbit, width, _tmpdst); \
|
---|
595 | FASTGETBITS(psrc, srcbit, width, _tmpsrc); \
|
---|
596 | DoRop(_tmpdst, rop, _tmpsrc, _tmpdst); \
|
---|
597 | u_FASTPUT(_tmpdst, dstbit, width, pdst); \
|
---|
598 | }
|
---|
599 |
|
---|
600 | #define getandputrrop(psrc, srcbit, dstbit, width, pdst, rop) \
|
---|
601 | { \
|
---|
602 | register PixelType _tmpsrc, _tmpdst; \
|
---|
603 | FASTGETBITS(pdst, dstbit, width, _tmpdst); \
|
---|
604 | FASTGETBITS(psrc, srcbit, width, _tmpsrc); \
|
---|
605 | _tmpdst = DoRRop(rop, _tmpsrc, _tmpdst); \
|
---|
606 | u_FASTPUT(_tmpdst, dstbit, width, pdst); \
|
---|
607 | }
|
---|
608 |
|
---|
609 | #define getandputbits0(psrc, srcbit, width, pdst) \
|
---|
610 | getandputbits(psrc, srcbit, 0, width, pdst)
|
---|
611 |
|
---|
612 | #define getandputrop0(psrc, srcbit, width, pdst, rop) \
|
---|
613 | getandputrop(psrc, srcbit, 0, width, pdst, rop)
|
---|
614 |
|
---|
615 | #define getandputrrop0(psrc, srcbit, width, pdst, rop) \
|
---|
616 | getandputrrop(psrc, srcbit, 0, width, pdst, rop)
|
---|
617 |
|
---|
618 |
|
---|
619 | #else /* Slow poke */
|
---|
620 |
|
---|
621 | /* pairs of getbits/putbits happen frequently. Some of the code can
|
---|
622 | * be shared or avoided in a few specific instances. It gets us a
|
---|
623 | * small advantage, so we do it. The getandput...0 macros are the only ones
|
---|
624 | * which speed things here. The others are here for compatibility w/the above
|
---|
625 | * FAST ones
|
---|
626 | */
|
---|
627 |
|
---|
628 | #define getandputbits(psrc, srcbit, dstbit, width, pdst) \
|
---|
629 | { \
|
---|
630 | register PixelType _tmpbits; \
|
---|
631 | getbits(psrc, srcbit, width, _tmpbits); \
|
---|
632 | putbits(_tmpbits, dstbit, width, pdst); \
|
---|
633 | }
|
---|
634 |
|
---|
635 | #define getandputrop(psrc, srcbit, dstbit, width, pdst, rop) \
|
---|
636 | { \
|
---|
637 | register PixelType _tmpbits; \
|
---|
638 | getbits(psrc, srcbit, width, _tmpbits) \
|
---|
639 | putbitsrop(_tmpbits, dstbit, width, pdst, rop) \
|
---|
640 | }
|
---|
641 |
|
---|
642 | #define getandputrrop(psrc, srcbit, dstbit, width, pdst, rop) \
|
---|
643 | { \
|
---|
644 | register PixelType _tmpbits; \
|
---|
645 | getbits(psrc, srcbit, width, _tmpbits) \
|
---|
646 | putbitsrrop(_tmpbits, dstbit, width, pdst, rop) \
|
---|
647 | }
|
---|
648 |
|
---|
649 |
|
---|
650 | #define getandputbits0(psrc, sbindex, width, pdst) \
|
---|
651 | { /* unroll the whole damn thing to see how it * behaves */ \
|
---|
652 | register int _flag = PPW - (sbindex); \
|
---|
653 | register PixelType _src; \
|
---|
654 | \
|
---|
655 | _src = SCRLEFT (*(psrc), (sbindex)); \
|
---|
656 | if ((width) > _flag) \
|
---|
657 | _src |= SCRRIGHT (*((psrc) + 1), _flag); \
|
---|
658 | \
|
---|
659 | *(pdst) = (*(pdst) & mfbGetstarttab((width))) | (_src & mfbGetendtab((width))); \
|
---|
660 | }
|
---|
661 |
|
---|
662 |
|
---|
663 | #define getandputrop0(psrc, sbindex, width, pdst, rop) \
|
---|
664 | { \
|
---|
665 | register int _flag = PPW - (sbindex); \
|
---|
666 | register PixelType _src; \
|
---|
667 | \
|
---|
668 | _src = SCRLEFT (*(psrc), (sbindex)); \
|
---|
669 | if ((width) > _flag) \
|
---|
670 | _src |= SCRRIGHT (*((psrc) + 1), _flag); \
|
---|
671 | DoRop(_src, rop, _src, *(pdst)); \
|
---|
672 | \
|
---|
673 | *(pdst) = (*(pdst) & mfbGetstarttab((width))) | (_src & mfbGetendtab((width))); \
|
---|
674 | }
|
---|
675 |
|
---|
676 | #define getandputrrop0(psrc, sbindex, width, pdst, rop) \
|
---|
677 | { \
|
---|
678 | int _flag = PPW - (sbindex); \
|
---|
679 | register PixelType _src; \
|
---|
680 | \
|
---|
681 | _src = SCRLEFT (*(psrc), (sbindex)); \
|
---|
682 | if ((width) > _flag) \
|
---|
683 | _src |= SCRRIGHT (*((psrc) + 1), _flag); \
|
---|
684 | _src = DoRRop(rop, _src, *(pdst)); \
|
---|
685 | \
|
---|
686 | *(pdst) = (*(pdst) & mfbGetstarttab((width))) | (_src & mfbGetendtab((width))); \
|
---|
687 | }
|
---|
688 |
|
---|
689 | #endif /* FASTGETBITS && FASTPUTBITS */
|
---|
690 |
|
---|
691 | #endif /* MFB_CONSTS_ONLY */
|
---|