b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/* $XFree86: xc/programs/Xserver/cfb/cfbmskbits.h,v 3.13tsi Exp $ */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/************************************************************
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncCopyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync All Rights Reserved
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncPermission to use, copy, modify, and distribute this
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncsoftware and its documentation for any purpose and without
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncfee is hereby granted, provided that the above copyright no-
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsynctice appear in all copies and that both that copyright no-
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsynctice and this permission notice appear in supporting docu-
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncmentation, and that the names of Sun or The Open Group
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncnot be used in advertising or publicity pertaining to
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncdistribution of the software without specific prior
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncwritten permission. Sun and The Open Group make no
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncrepresentations about the suitability of this software for
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncany purpose. It is provided "as is" without any express or
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncimplied warranty.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncSUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncPROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncTHE USE OR PERFORMANCE OF THIS SOFTWARE.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync********************************************************/
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/* $Xorg: cfbmskbits.h,v 1.3 2000/08/17 19:48:14 cpqbld Exp $ */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/* Optimizations for PSZ == 32 added by Kyle Marvin (marvin@vitec.com) */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#if defined(XFREE86) || ( defined(__OpenBSD__) && defined(__alpha__) ) \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync || (defined(__bsdi__))
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * ==========================================================================
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Converted from mfb to support memory-mapped color framebuffer by smarks@sun,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * April-May 1987.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * The way I did the conversion was to consider each longword as an
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * array of four bytes instead of an array of 32 one-bit pixels. So
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * getbits() and putbits() retain much the same calling sequence, but
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * they move bytes around instead of bits. Of course, this entails the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * removal of all of the one-bit-pixel dependencies from the other
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * files, but the major bit-hacking stuff should be covered here.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * I've created some new macros that make it easier to understand what's
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * going on in the pixel calculations, and that make it easier to change the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * pixel size.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * name explanation
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * ---- -----------
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PSZ pixel size (in bits)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PGSZ pixel group size (in bits)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PGSZB pixel group size (in bytes)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PGSZBMSK mask with lowest PGSZB bits set to 1
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PPW pixels per word (pixels per pixel group)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PPWMSK mask with lowest PPW bits set to 1
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PLST index of last pixel in a word (should be PPW-1)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PIM pixel index mask (index within a pixel group)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PWSH pixel-to-word shift (should be log2(PPW))
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PMSK mask with lowest PSZ bits set to 1
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Here are some sample values. In the notation cfbA,B: A is PSZ, and
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * B is PGSZB. All the other values are derived from these
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * two. This table does not show all combinations!
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * name cfb8,4 cfb24,4 cfb32,4 cfb8,8 cfb24,8 cfb32,8
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * ---- ------ ------- ------ ------ ------ -------
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PSZ 8 24 32 8 24 32
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PGSZ 32 32 32 64 64 64
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PGSZB 4 4 4 8 8 8
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PGSZBMSK 0xF 0xF? 0xF 0xFF 0xFF 0xFF
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PPW 4 1 1 8 2 2
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PPWMSK 0xF 0x1 0x1 0xFF 0x3? 0x3
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PLST 3 0 0 7 1 1
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PIM 0x3 0x0 0x0 0x7 0x1? 0x1
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PWSH 2 0 0 3 1 1
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PMSK 0xFF 0xFFFFFF 0xFFFFFFFF 0xFF 0xFFFFFF 0xFFFFFFFF
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * I have also added a new macro, PFILL, that takes one pixel and
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * replicates it throughout a word. This macro definition is dependent
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * upon pixel and word size; it doesn't use macros like PPW and so
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * forth. Examples: for monochrome, PFILL(1) => 0xffffffff, PFILL(0) =>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * 0x00000000. For 8-bit color, PFILL(0x5d) => 0x5d5d5d5d. This macro
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * is used primarily for replicating a plane mask into a word.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Color framebuffers operations also support the notion of a plane
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * mask. This mask determines which planes of the framebuffer can be
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * altered; the others are left unchanged. I have added another
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * parameter to the putbits and putbitsrop macros that is the plane
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * ==========================================================================
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Keith Packard (keithp@suse.com)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * 64bit code is no longer supported; it requires DIX support
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * for repadding images which significantly impacts performance
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PSZ needs to be defined before we get here. Usually it comes from a
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * -DPSZ=foo on the compilation command line.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PixelGroup is the data type used to operate on groups of pixels.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * We typedef it here to CARD32 with the assumption that you
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * want to manipulate 32 bits worth of pixels at a time as you can. If CARD32
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * is not appropriate for your server, define it to something else
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * before including this file. In this case you will also have to define
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * PGSZB to the size in bytes of PixelGroup.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif /* PixelGroup */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#define PPWMSK (((PixelGroup)1 << PPW) - 1) /* instead of BITMSK */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/* set PWSH = log2(PPW) using brute force */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif /* PPW == 16 */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif /* PPW == 8 */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif /* PPW == 4 */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif /* PPW == 2 */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif /* PPW == 1 */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/* Defining PIXEL_ADDR means that individual pixels are addressable by this
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * machine (as type PixelType). A possible CFB architecture which supported
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * 8-bits-per-pixel on a non byte-addressable machine would not have this
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Defining FOUR_BIT_CODE means that cfb knows how to stipple on this machine;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * eventually, stippling code for 16 and 32 bit devices should be written
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * which would allow them to also use FOUR_BIT_CODE. There isn't that
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * much to do in those cases, but it would make them quite a bit faster.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/*#undef PIM
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#define PIM 3*/
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/* the following notes use the following conventions:
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncSCREEN LEFT SCREEN RIGHT
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncin this file and maskbits.c, left and right refer to screen coordinates,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncNOT bit numbering in registers.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsynccfbstarttab[n]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync pixels[0,n-1] = 0's pixels[n,PPW-1] = 1's
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsynccfbendtab[n] =
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync pixels[0,n-1] = 1's pixels[n,PPW-1] = 0's
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsynccfbstartpartial[], cfbendpartial[]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync these are used as accelerators for doing putbits and masking out
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncbits that are all contained between longword boudaries. the extra
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync256 bytes of data seems a small price to pay -- code is smaller,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncand narrow things (e.g. window borders) go faster.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncthe names may seem misleading; they are derived not from which end
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncof the word the bits are turned on, but at which end of a scanline
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncthe table tends to be used.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsynclook at the tables and macros to understand boundary conditions.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync(careful readers will note that starttab[n] = ~endtab[n] for n != 0)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync-----------------------------------------------------------------------
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncthese two macros depend on the screen's bit ordering.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncin both of them x is a screen position. they are used to
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsynccombine bits collected from multiple longwords into a
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncsingle destination longword, and to unpack a single
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncsource longword into multiple destinations.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncSCRLEFT(dst, x)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync takes dst[x, PPW] and moves them to dst[0, PPW-x]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync the contents of the rest of dst are 0 ONLY IF
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync dst is UNSIGNED.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync is cast as an unsigned.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync this is a right shift on the VAX, left shift on
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync Sun and pc-rt.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncSCRRIGHT(dst, x)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync takes dst[0,x] and moves them to dst[PPW-x, PPW]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync the contents of the rest of dst are 0 ONLY IF
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync dst is UNSIGNED.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync this is a left shift on the VAX, right shift on
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync Sun and pc-rt.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncthe remaining macros are cpu-independent; all bit order dependencies
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncare built into the tables and the two macros above.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncmaskbits(x, w, startmask, endmask, nlw)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync for a span of width w starting at position x, returns
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsynca mask for ragged pixels at start, mask for ragged pixels at end,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncand the number of whole longwords between the ends.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncmaskpartialbits(x, w, mask)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync works like maskbits(), except all the pixels are in the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync same longword (i.e. (x&0xPIM + w) <= PPW)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncmask32bits(x, w, startmask, endmask, nlw)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync as maskbits, but does not calculate nlw. it is used by
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync cfbGlyphBlt to put down glyphs <= PPW bits wide.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncgetbits(psrc, x, w, dst)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync starting at position x in psrc (x < PPW), collect w
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync pixels and put them in the screen left portion of dst.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync psrc is a longword pointer. this may span longword boundaries.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync it special-cases fetching all w bits from one longword.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync +--------+--------+ +--------+
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync | | m |n| | ==> | m |n| |
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync +--------+--------+ +--------+
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync psrc psrc+1 dst
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync m = PPW - x
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync implementation:
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync get m pixels, move to screen-left of dst, zeroing rest of dst;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync get n pixels from next word, move screen-right by m, zeroing
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync lower m pixels of word.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync OR the two things together.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncputbits(src, x, w, pdst, planemask)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync starting at position x in pdst, put down the screen-leftmost
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync w bits of src. pdst is a longword pointer. this may
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync span longword boundaries.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync it special-cases putting all w bits into the same longword.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync +--------+ +--------+--------+
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync | m |n| | ==> | | m |n| |
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync +--------+ +--------+--------+
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync dst pdst pdst+1
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync m = PPW - x
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync implementation:
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync get m pixels, shift screen-right by x, zero screen-leftmost x
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync pixels; zero rightmost m bits of *pdst and OR in stuff
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync from before the semicolon.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync shift src screen-left by m, zero bits n-32;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync zero leftmost n pixels of *(pdst+1) and OR in the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync stuff from before the semicolon.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncputbitsrop(src, x, w, pdst, planemask, ROP)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync like putbits but calls DoRop with the rasterop ROP (see cfb.h for
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncgetleftbits(psrc, w, dst)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync get the leftmost w (w<=PPW) bits from *psrc and put them
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync in dst. this is used by the cfbGlyphBlt code for glyphs
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync <=PPW bits wide.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#else /* (BITMAP_BIT_ORDER == LSBFirst) */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif /* (BITMAP_BIT_ORDER == MSBFirst) */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Note that the shift direction is independent of the byte ordering of the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * machine. The following is portable code.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif /* PPW == 16 */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#define PFILL(p) (p)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Reduced raster op - using precomputed values, perform the above
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * in three instructions
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#define DoRRop(dst, and, xor) (((dst) & (and)) ^ (xor))
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mask = cfbstartpartial[(x) & 3] & cfbendpartial[((x)+(w)) & 3];
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync register int idx; \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync dst = BitLeft((*(psrc) &cfbmask[idx]), cfb24Shift[idx]); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync dst = BitLeft((*(psrc) &cfbmask[idx]), cfb24Shift[idx]) | \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync BitRight(((*((psrc)+1)) &cfbmask[idx+1]), cfb24Shift[idx+1]); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#define putbits24(src, w, pdst, planemask, index) {\
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync register unsigned int idx; \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx]); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx])| \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync BitRight(((*((pdst)+1)) &cfbmask[idx+1]), cfb24Shift[idx+1]); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync (BitLeft(dstpixel, cfb24Shift[idx]) & cfbmask[idx]); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync *(pdst) |= (BitRight(dstpixel, cfb24Shift[idx]) & cfbmask[idx]); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#define putbitsrop24(src, x, pdst, planemask, rop) \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync register unsigned int idx; \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx]); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx])| \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync BitRight(((*((pdst)+1)) &cfbmask[idx+1]), cfb24Shift[idx+1]); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync *((pdst)+1) = ((*((pdst)+1)) & cfbrmask[idx+1]) | \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync (BitLeft(dstpixel, cfb24Shift[idx+1]) & (cfbmask[idx+1])); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync *(pdst) |= (BitRight(dstpixel, cfb24Shift[idx]) & cfbmask[idx]); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync# else /* PSZ == 24 && PPW == 1 */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mask = cfbstartpartial[(x) & PIM] & cfbendpartial[((x) + (w)) & PIM];
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#define putbitsrop24(src, x, pdst, planemask, rop) \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif /* PSZ == 24 && PPW == 1 */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncif ( ((x) + (w)) <= PPW) \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncif ( ((x)+(w)) <= PPW) \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync *(pdst) = (*(pdst) & ~tmpmask) | (SCRRIGHT(src, x) & tmpmask); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync unsigned int m; \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync unsigned int n; \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync n = (w) - m; \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync *((pdst)+1) = (*((pdst)+1) & (cfbstarttab[n] | ~pm)) | \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync asm ("bfextu %3{%1:%2},%0" \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync : "=d" (dst) : "di" (x), "di" (w), "o" (*(char *)(psrc)))
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync asm ("bfins %3,%0{%1:%2}" \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync : "di" (x), "di" (w), "d" (src), "0" (*(char *) (pdst)))
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync FASTPUTBITS(SCRRIGHT(src, PPW-(w)), (x) * PSZ, (w) * PSZ, pdst); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif /* mc68020 */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#define putbitsrop(src, x, w, pdst, planemask, rop) \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncif ( ((x)+(w)) <= PPW) \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync n = (w) - m; \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync *(pdst) = (*(pdst) & (cfbendtab[x] | ~pm)) | (t2 & (cfbstarttab[x] & pm));\
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync *((pdst)+1) = (*((pdst)+1) & (cfbstarttab[n] | ~pm)) | \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#else /* PSZ == 32 && PPW == 1*/
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * These macros can be optimized for 32-bit pixels since there is no
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * need to worry about left/right edge masking. These macros were
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * derived from the above using the following reductions:
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * - x & PIW = 0 [since PIW = 0]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * - all masking tables are only indexed by 0 [ due to above ]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * - cfbstartab[0] and cfbendtab[0] = 0 [ no left/right edge masks]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * - cfbstartpartial[0] and cfbendpartial[0] = ~0 [no partial pixel mask]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Macro reduction based upon constants cannot be performed automatically
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * by the compiler since it does not know the contents of the masking
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * For 32-bit operations, getbits(), putbits(), and putbitsrop()
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * will only be invoked with x = 0 and w = PPW (1). The getbits()
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * macro is only called within left/right edge logic, which doesn't
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * happen for 32-bit pixels.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync *(pdst) = (*(pdst) & ~planemask) | (src & planemask);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#define putbitsrop(src, x, w, pdst, planemask, rop) \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync *(pdst) = (*(pdst) & ~planemask) | (t1 & planemask); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif /* PSZ != 32 */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Use these macros only when you're using the MergeRop stuff
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/* useful only when not spanning destination longwords */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/* useful only when spanning destination longwords */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync pdst[0] = DoMaskMergeRop(_t1,pdst[0],_startmask); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncif ((x) + (w) <= PPW) {\
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#define getleftbits(psrc, w, dst) dst = *((unsigned int *) psrc)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync dst = BitLeft(((*((unsigned int *) psrc))&cfbmask[index]), cfb24Shift[index]); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync dst |= BitRight(((*((unsigned int *) psrc)+1)&cfbmask[index]), cfb4Shift[index]); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync dst = BitLeft((*((unsigned int *) psrc)),cfb24Shift[index]); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif /* GETLEFTBITS_ALIGNMENT == 1 */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if ( ((x) + (w)) > 32) \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync dst |= (BitRight((unsigned) *((psrc)+1), 32-(x))); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync getglyphbits( ((unsigned int *)(((char *)(psrc))-1)), 8, (w), (dst) ); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif /* GETLEFTBITS_ALIGNMENT == 2 */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif /* GETLEFTBITS_ALIGNMENT == 4 */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * getstipplepixels( psrcstip, x, w, ones, psrcpix, destpix )
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Converts bits to pixels in a reasonable way. Takes w (1 <= w <= PPW)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * bits from *psrcstip, starting at bit x; call this a quartet of bits.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Then, takes the pixels from *psrcpix corresponding to the one-bits (if
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * ones is TRUE) or the zero-bits (if ones is FALSE) of the quartet
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * and puts these pixels into destpix.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * getstipplepixels( &(0x08192A3B), 17, 4, 1, &(0x4C5D6E7F), dest )
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * 0x08192A3B = 0000 1000 0001 1001 0010 1010 0011 1011
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * This will take 4 bits starting at bit 17, so the quartet is 0x5 = 0101.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * It will take pixels from 0x4C5D6E7F corresponding to the one-bits in this
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * quartet, so dest = 0x005D007F.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * XXX Works with both byte order.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * XXX This works for all values of x and w within a doubleword.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#define getstipplepixels( psrcstip, x, w, ones, psrcpix, destpix ) \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync q = (*(psrcstip)) << m; \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync q = (*(psrcstip)) >> -m; \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync *(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/* I just copied this to get the linker satisfied on PowerPC,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * so this may not be correct at all.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#define getstipplepixels24(psrcstip,xt,ones,psrcpix,destpix,stipindex) \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync *(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#else /* BITMAP_BIT_ORDER == LSB */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/* this must load 32 bits worth; for most machines, thats an int */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#define getstipplepixels( psrcstip, xt, w, ones, psrcpix, destpix ) \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync q |= (CfbFetchUnaligned((psrcstip)+1)) << ((PPW*PSZ)-(xt)); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync *(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#define getstipplepixels24(psrcstip,xt,w,ones,psrcpix,destpix,stipindex,srcindex,dstindex) \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync register unsigned int sidx; \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync register unsigned int didx; \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/* if((srcindex)!=0)*/ \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/* src = (((*(psrcpix)) << cfb24Shift[sidx]) & (cfbmask[sidx])) |*/ \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/* (((*((psrcpix)+1)) << cfb24Shift[sidx+1]) & (cfbmask[sidx+1])); */\
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync (BitLeft(src, cfb24Shift[didx]) & (cfbmask[didx])); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync *(destpix) |= (BitRight(src, cfb24Shift[didx]) & cfbmask[didx]); \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#define getstipplepixels24(psrcstip,xt,ones,psrcpix,destpix,stipindex) \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync *(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync#endif /* PSZ == 24 */