226 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			226 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * $Xorg: cfbrrop.c,v 1.4 2001/02/09 02:04:38 xorgcvs Exp $
 | |
|  *
 | |
| Copyright 1989, 1998  The Open Group
 | |
| 
 | |
| Permission to use, copy, modify, distribute, and sell this software and its
 | |
| documentation for any purpose is hereby granted without fee, provided that
 | |
| the above copyright notice appear in all copies and that both that
 | |
| copyright notice and this permission notice appear in supporting
 | |
| documentation.
 | |
| 
 | |
| The above copyright notice and this permission notice shall be included in
 | |
| all copies or substantial portions of the Software.
 | |
| 
 | |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | |
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | |
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 | |
| OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 | |
| AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | |
| CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | |
| 
 | |
| Except as contained in this notice, the name of The Open Group shall not be
 | |
| used in advertising or otherwise to promote the sale, use or other dealings
 | |
| in this Software without prior written authorization from The Open Group.
 | |
|  *
 | |
|  * Author:  Keith Packard, MIT X Consortium
 | |
|  */
 | |
| /* $XFree86: xc/programs/Xserver/cfb/cfbrrop.c,v 1.5 2001/10/28 03:33:02 tsi Exp $ */
 | |
| 
 | |
| /* cfb reduced rasterop computations */
 | |
| 
 | |
| #include "X.h"
 | |
| #include "Xmd.h"
 | |
| #include "Xproto.h"
 | |
| #include "cfb.h"
 | |
| #include "cfbmskbits.h"
 | |
| 
 | |
| /* A description:
 | |
|  *
 | |
|  * There are four possible operations on each bit in the destination word,
 | |
|  *
 | |
|  *	    1	2   3	4
 | |
|  *
 | |
|  *    0	    0	0   1	1
 | |
|  *    1	    0	1   0	1
 | |
|  *
 | |
|  * On examination of the reduced rop equation (dst = (dst & and) ^ xor),
 | |
|  * these four fall to reduced rops as follows:
 | |
|  *
 | |
|  *  and	    0	1   1	0
 | |
|  *  xor	    0	0   1	1
 | |
|  *
 | |
|  * or, (if 'and' is expensive) (dst = (dst | or) ^ xor)
 | |
|  *
 | |
|  *  or	    1	0   0	1
 | |
|  *  xor	    1	0   1	0
 | |
|  *
 | |
|  * The trouble with using this later equation is that trivial
 | |
|  * rasterop reduction is more difficult; some common rasterops
 | |
|  * use complicated expressions of xor/and instead of the simple
 | |
|  * ones while other common rasterops are not made any simpler:
 | |
|  *
 | |
|  * GXcopy:	*dst = ~xor		instead of  *dst = xor
 | |
|  * GXand:	*dst = *dst & ~or	instead of  *dst = *dst & and
 | |
|  * GXor:	*dst = *dst | or	instead of  *dst = *dst | xor
 | |
|  * GXxor:	*dst = *dst ^ xor	instead of  *dst = *dst ^ xor
 | |
|  *
 | |
|  * If you're really set on using this second mechanism, the changes
 | |
|  * are pretty simple.
 | |
|  *
 | |
|  * All that remains is to provide a mechanism for computing and/xor values
 | |
|  * based on the raster op and foreground value.
 | |
|  *
 | |
|  * The 16 rops fall as follows, with the associated reduced
 | |
|  * rop and/xor and or/xor values.  The values in parenthesis following the
 | |
|  * reduced values gives an equation using the source value for
 | |
|  * the reduced value, and is one of {0, src, ~src, 1} as appropriate.
 | |
|  *
 | |
|  *	clear		and		andReverse	copy
 | |
|  *     src  0	1	    0   1	    0	1	    0	1
 | |
|  *  dst	0   0	0	0   0   0	0   0	1	0   0	1
 | |
|  *	1   0	0	1   0   1	1   0	0	1   0	1
 | |
|  *
 | |
|  *  and	    0	0 (0)	    0   1 (src)	    0	1 (src)	    0	0 (0)
 | |
|  *  xor	    0	0 (0)	    0   0 (0)	    0	1 (src)	    0	1 (src)
 | |
|  *
 | |
|  *  or	    1	1 (1)	    1	0 (~src)    1	0 (~src)    1	1 (1)
 | |
|  *  xor	    1	1 (1)	    1	0 (~src)    1	1 (1)	    1	0 (~src)
 | |
|  *
 | |
|  *	andInverted	noop		xor		or
 | |
|  *     src  0	1	    0   1	    0	1	    0	1
 | |
|  *  dst	0   0	0	0   0   0	0   0	1	0   0	1
 | |
|  *	1   1	0	1   1   1	1   1	0	1   1	1
 | |
|  *
 | |
|  *  and	    1	0 (~src)    1   1 (1)	    1	1 (1)	    1	0 (~src)
 | |
|  *  xor	    0	0 (0)	    0   0 (0)	    0	1 (src)	    0	1 (src)
 | |
|  *
 | |
|  *  or	    0	1 (src)	    0	0 (0)	    0	0 (0)	    0	1 (src)
 | |
|  *  xor	    0	1 (src)	    0	0 (0)	    0	1 (src)	    0	0 (0)
 | |
|  *
 | |
|  *	nor		equiv		invert		orReverse
 | |
|  *     src  0	1	    0   1	    0	1	    0	1
 | |
|  *  dst	0   1	0	0   1   0	0   1	1	0   1	1
 | |
|  *	1   0	0	1   0   1	1   0	0	1   0	1
 | |
|  *
 | |
|  *  and	    1	0 (~src)    1   1 (1)	    1	1 (1)	    1	0 (~src)
 | |
|  *  xor	    1	0 (~src)    1   0 (~src)    1	1 (1)	    1	1 (1)
 | |
|  *
 | |
|  *  or	    0	1 (src)	    0	0 (0)	    0	0 (0)	    0	1 (src)
 | |
|  *  xor	    1	1 (1)	    1	0 (~src)    1	1 (1)	    1	0 (~src)
 | |
|  *
 | |
|  *	copyInverted	orInverted	nand		set
 | |
|  *     src  0	1	    0   1	    0	1	    0	1
 | |
|  *  dst	0   1	0	0   1   0	0   1	1	0   1	1
 | |
|  *	1   1	0	1   1   1	1   1	0	1   1	1
 | |
|  *
 | |
|  *  and	    0	0 (0)	    0   1 (src)	    0	1 (src)	    0	0 (0)
 | |
|  *  xor	    1	0 (~src)    1   0 (~src)    1	1 (1)	    1	1 (1)
 | |
|  *
 | |
|  *  or	    1	1 (1)	    1	0 (~src)    1	0 (~src)    1	1 (1)
 | |
|  *  xor	    0	1 (src)	    0	0 (0)	    0	1 (src)	    0	0 (0)
 | |
|  */
 | |
| 
 | |
| int
 | |
| cfbReduceRasterOp (rop, fg, pm, andp, xorp)
 | |
|     int		    rop;
 | |
|     CfbBits   fg, pm;
 | |
|     CfbBits   *andp, *xorp;
 | |
| {
 | |
|     CfbBits   and, xor;
 | |
|     int		    rrop;
 | |
| 
 | |
|     fg = PFILL (fg);
 | |
|     pm = PFILL (pm);
 | |
|     switch (rop)
 | |
|     {
 | |
|     case GXclear:
 | |
|     	and = 0;
 | |
|     	xor = 0;
 | |
| 	break;
 | |
|     case GXand:
 | |
| 	and = fg;
 | |
| 	xor = 0;
 | |
| 	break;
 | |
|     case GXandReverse:
 | |
| 	and = fg;
 | |
| 	xor = fg;
 | |
| 	break;
 | |
|     case GXcopy:
 | |
| 	and = 0;
 | |
| 	xor = fg;
 | |
| 	break;
 | |
|     case GXandInverted:
 | |
| 	and = ~fg;
 | |
| 	xor = 0;
 | |
| 	break;
 | |
|     case GXnoop:
 | |
| 	and = ~0;
 | |
| 	xor = 0;
 | |
| 	break;
 | |
|     case GXxor:
 | |
| 	and = ~0;
 | |
| 	xor = fg;
 | |
| 	break;
 | |
|     case GXor:
 | |
| 	and = ~fg;
 | |
| 	xor = fg;
 | |
| 	break;
 | |
|     case GXnor:
 | |
| 	and = ~fg;
 | |
| 	xor = ~fg;
 | |
| 	break;
 | |
|     case GXequiv:
 | |
| 	and = ~0;
 | |
| 	xor = ~fg;
 | |
| 	break;
 | |
|     case GXinvert:
 | |
| 	and = ~0;
 | |
| 	xor = ~0;
 | |
| 	break;
 | |
|     case GXorReverse:
 | |
| 	and = ~fg;
 | |
| 	xor = ~0;
 | |
| 	break;
 | |
|     case GXcopyInverted:
 | |
| 	and = 0;
 | |
| 	xor = ~fg;
 | |
| 	break;
 | |
|     case GXorInverted:
 | |
| 	and = fg;
 | |
| 	xor = ~fg;
 | |
| 	break;
 | |
|     case GXnand:
 | |
| 	and = fg;
 | |
| 	xor = ~0;
 | |
| 	break;
 | |
|     case GXset:
 | |
| 	and = 0;
 | |
| 	xor = ~0;
 | |
| 	break;
 | |
|     default:
 | |
| 	and = xor = 0;
 | |
| 	break;
 | |
|     }
 | |
|     and |= ~pm;
 | |
|     xor &= pm;
 | |
|     *andp = and;
 | |
|     *xorp = xor;
 | |
|     /* check for some special cases to reduce computation */
 | |
|     if (and == 0)
 | |
| 	rrop = GXcopy;
 | |
|     /* nothing checks for GXnoop
 | |
|     else if (and == ~0 && xor == 0)
 | |
| 	rrop = GXnoop;
 | |
|     */
 | |
|     else if (and == ~0)
 | |
| 	rrop = GXxor;
 | |
|     else if (xor == 0)
 | |
| 	rrop = GXand;
 | |
|     else if ( (and ^ xor) == ~0) /* fix XBUG 6541 */
 | |
| 	rrop = GXor;
 | |
|     else
 | |
| 	rrop = GXset;   /* rop not reduced */
 | |
|     return rrop;
 | |
| }
 |