fbsolid.c revision 05b261ec
105b261ecSmrg/*
205b261ecSmrg * Copyright © 1998 Keith Packard
305b261ecSmrg *
405b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its
505b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that
605b261ecSmrg * the above copyright notice appear in all copies and that both that
705b261ecSmrg * copyright notice and this permission notice appear in supporting
805b261ecSmrg * documentation, and that the name of Keith Packard not be used in
905b261ecSmrg * advertising or publicity pertaining to distribution of the software without
1005b261ecSmrg * specific, written prior permission.  Keith Packard makes no
1105b261ecSmrg * representations about the suitability of this software for any purpose.  It
1205b261ecSmrg * is provided "as is" without express or implied warranty.
1305b261ecSmrg *
1405b261ecSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1505b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
1605b261ecSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1705b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
1805b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
1905b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2005b261ecSmrg * PERFORMANCE OF THIS SOFTWARE.
2105b261ecSmrg */
2205b261ecSmrg
2305b261ecSmrg#define FbSelectPart(xor,o,t)    xor
2405b261ecSmrg
2505b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
2605b261ecSmrg#include <dix-config.h>
2705b261ecSmrg#endif
2805b261ecSmrg
2905b261ecSmrg#include "fb.h"
3005b261ecSmrg
3105b261ecSmrgvoid
3205b261ecSmrgfbSolid (FbBits	    *dst,
3305b261ecSmrg	 FbStride   dstStride,
3405b261ecSmrg	 int	    dstX,
3505b261ecSmrg	 int	    bpp,
3605b261ecSmrg
3705b261ecSmrg	 int	    width,
3805b261ecSmrg	 int	    height,
3905b261ecSmrg
4005b261ecSmrg	 FbBits	    and,
4105b261ecSmrg	 FbBits	    xor)
4205b261ecSmrg{
4305b261ecSmrg    FbBits  startmask, endmask;
4405b261ecSmrg    int	    n, nmiddle;
4505b261ecSmrg    int	    startbyte, endbyte;
4605b261ecSmrg
4705b261ecSmrg#ifdef FB_24BIT
4805b261ecSmrg    if (bpp == 24 && (!FbCheck24Pix(and) || !FbCheck24Pix(xor)))
4905b261ecSmrg    {
5005b261ecSmrg	fbSolid24 (dst, dstStride, dstX, width, height, and, xor);
5105b261ecSmrg	return;
5205b261ecSmrg    }
5305b261ecSmrg#endif
5405b261ecSmrg    dst += dstX >> FB_SHIFT;
5505b261ecSmrg    dstX &= FB_MASK;
5605b261ecSmrg    FbMaskBitsBytes(dstX, width, and == 0, startmask, startbyte,
5705b261ecSmrg		    nmiddle, endmask, endbyte);
5805b261ecSmrg    if (startmask)
5905b261ecSmrg	dstStride--;
6005b261ecSmrg    dstStride -= nmiddle;
6105b261ecSmrg    while (height--)
6205b261ecSmrg    {
6305b261ecSmrg	if (startmask)
6405b261ecSmrg	{
6505b261ecSmrg	    FbDoLeftMaskByteRRop(dst,startbyte,startmask,and,xor);
6605b261ecSmrg	    dst++;
6705b261ecSmrg	}
6805b261ecSmrg	n = nmiddle;
6905b261ecSmrg	if (!and)
7005b261ecSmrg	    while (n--)
7105b261ecSmrg		WRITE(dst++, xor);
7205b261ecSmrg	else
7305b261ecSmrg	    while (n--)
7405b261ecSmrg	    {
7505b261ecSmrg		WRITE(dst, FbDoRRop (READ(dst), and, xor));
7605b261ecSmrg                dst++;
7705b261ecSmrg	    }
7805b261ecSmrg	if (endmask)
7905b261ecSmrg	    FbDoRightMaskByteRRop(dst,endbyte,endmask,and,xor);
8005b261ecSmrg	dst += dstStride;
8105b261ecSmrg    }
8205b261ecSmrg}
8305b261ecSmrg
8405b261ecSmrg#ifdef FB_24BIT
8505b261ecSmrgvoid
8605b261ecSmrgfbSolid24 (FbBits   *dst,
8705b261ecSmrg	   FbStride dstStride,
8805b261ecSmrg	   int	    dstX,
8905b261ecSmrg
9005b261ecSmrg	   int	    width,
9105b261ecSmrg	   int	    height,
9205b261ecSmrg
9305b261ecSmrg	   FbBits   and,
9405b261ecSmrg	   FbBits   xor)
9505b261ecSmrg{
9605b261ecSmrg    FbBits  startmask, endmask;
9705b261ecSmrg    FbBits  xor0 = 0, xor1 = 0, xor2 = 0;
9805b261ecSmrg    FbBits  and0 = 0, and1 = 0, and2 = 0;
9905b261ecSmrg    FbBits  xorS = 0, andS = 0, xorE = 0, andE = 0;
10005b261ecSmrg    int	    n, nmiddle;
10105b261ecSmrg    int	    rotS, rot;
10205b261ecSmrg
10305b261ecSmrg    dst += dstX >> FB_SHIFT;
10405b261ecSmrg    dstX &= FB_MASK;
10505b261ecSmrg    /*
10605b261ecSmrg     * Rotate pixel values this far across the word to align on
10705b261ecSmrg     * screen pixel boundaries
10805b261ecSmrg     */
10905b261ecSmrg    rot = FbFirst24Rot (dstX);
11005b261ecSmrg    FbMaskBits (dstX, width, startmask, nmiddle, endmask);
11105b261ecSmrg    if (startmask)
11205b261ecSmrg	dstStride--;
11305b261ecSmrg    dstStride -= nmiddle;
11405b261ecSmrg
11505b261ecSmrg    /*
11605b261ecSmrg     * Precompute rotated versions of the rasterop values
11705b261ecSmrg     */
11805b261ecSmrg    rotS = rot;
11905b261ecSmrg    xor = FbRot24(xor,rotS);
12005b261ecSmrg    and = FbRot24(and,rotS);
12105b261ecSmrg    if (startmask)
12205b261ecSmrg    {
12305b261ecSmrg	xorS = xor;
12405b261ecSmrg	andS = and;
12505b261ecSmrg	xor = FbNext24Pix(xor);
12605b261ecSmrg	and = FbNext24Pix(and);
12705b261ecSmrg    }
12805b261ecSmrg
12905b261ecSmrg    if (nmiddle)
13005b261ecSmrg    {
13105b261ecSmrg	xor0 = xor;
13205b261ecSmrg	and0 = and;
13305b261ecSmrg	xor1 = FbNext24Pix(xor0);
13405b261ecSmrg	and1 = FbNext24Pix(and0);
13505b261ecSmrg	xor2 = FbNext24Pix(xor1);
13605b261ecSmrg	and2 = FbNext24Pix(and1);
13705b261ecSmrg    }
13805b261ecSmrg
13905b261ecSmrg    if (endmask)
14005b261ecSmrg    {
14105b261ecSmrg	switch (nmiddle % 3) {
14205b261ecSmrg	case 0:
14305b261ecSmrg	    xorE = xor;
14405b261ecSmrg	    andE = and;
14505b261ecSmrg	    break;
14605b261ecSmrg	case 1:
14705b261ecSmrg	    xorE = xor1;
14805b261ecSmrg	    andE = and1;
14905b261ecSmrg	    break;
15005b261ecSmrg	case 2:
15105b261ecSmrg	    xorE = xor2;
15205b261ecSmrg	    andE = and2;
15305b261ecSmrg	    break;
15405b261ecSmrg	}
15505b261ecSmrg    }
15605b261ecSmrg
15705b261ecSmrg    while (height--)
15805b261ecSmrg    {
15905b261ecSmrg	if (startmask)
16005b261ecSmrg	{
16105b261ecSmrg	    WRITE(dst, FbDoMaskRRop(READ(dst), andS, xorS, startmask));
16205b261ecSmrg            dst++;
16305b261ecSmrg	}
16405b261ecSmrg	n = nmiddle;
16505b261ecSmrg	if (!and0)
16605b261ecSmrg	{
16705b261ecSmrg	    while (n >= 3)
16805b261ecSmrg	    {
16905b261ecSmrg		WRITE(dst++, xor0);
17005b261ecSmrg		WRITE(dst++, xor1);
17105b261ecSmrg		WRITE(dst++, xor2);
17205b261ecSmrg		n -= 3;
17305b261ecSmrg	    }
17405b261ecSmrg	    if (n)
17505b261ecSmrg	    {
17605b261ecSmrg		WRITE(dst++, xor0);
17705b261ecSmrg		n--;
17805b261ecSmrg		if (n)
17905b261ecSmrg		{
18005b261ecSmrg		    WRITE(dst++, xor1);
18105b261ecSmrg		}
18205b261ecSmrg	    }
18305b261ecSmrg	}
18405b261ecSmrg	else
18505b261ecSmrg	{
18605b261ecSmrg	    while (n >= 3)
18705b261ecSmrg	    {
18805b261ecSmrg		WRITE(dst, FbDoRRop (READ(dst), and0, xor0));
18905b261ecSmrg                dst++;
19005b261ecSmrg		WRITE(dst, FbDoRRop (READ(dst), and1, xor1));
19105b261ecSmrg                dst++;
19205b261ecSmrg		WRITE(dst, FbDoRRop (READ(dst), and2, xor2));
19305b261ecSmrg                dst++;
19405b261ecSmrg		n -= 3;
19505b261ecSmrg	    }
19605b261ecSmrg	    if (n)
19705b261ecSmrg	    {
19805b261ecSmrg		WRITE(dst, FbDoRRop (READ(dst), and0, xor0));
19905b261ecSmrg                dst++;
20005b261ecSmrg		n--;
20105b261ecSmrg		if (n)
20205b261ecSmrg		{
20305b261ecSmrg		    WRITE(dst, FbDoRRop (READ(dst), and1, xor1));
20405b261ecSmrg                    dst++;
20505b261ecSmrg		}
20605b261ecSmrg	    }
20705b261ecSmrg	}
20805b261ecSmrg	if (endmask)
20905b261ecSmrg	    WRITE(dst, FbDoMaskRRop (READ(dst), andE, xorE, endmask));
21005b261ecSmrg	dst += dstStride;
21105b261ecSmrg    }
21205b261ecSmrg}
21305b261ecSmrg#endif
214