fbsolid.c revision 35c4bbdf
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
3235c4bbdfSmrgfbSolid(FbBits * dst,
3335c4bbdfSmrg        FbStride dstStride,
3435c4bbdfSmrg        int dstX, int bpp, int width, int height, FbBits and, FbBits xor)
3505b261ecSmrg{
3635c4bbdfSmrg    FbBits startmask, endmask;
3735c4bbdfSmrg    int n, nmiddle;
3835c4bbdfSmrg    int startbyte, endbyte;
3905b261ecSmrg
4035c4bbdfSmrg    if (bpp == 24 && (!FbCheck24Pix(and) || !FbCheck24Pix(xor))) {
4135c4bbdfSmrg        fbSolid24(dst, dstStride, dstX, width, height, and, xor);
4235c4bbdfSmrg        return;
4305b261ecSmrg    }
4405b261ecSmrg    dst += dstX >> FB_SHIFT;
4505b261ecSmrg    dstX &= FB_MASK;
4635c4bbdfSmrg    FbMaskBitsBytes(dstX, width, and == 0, startmask, startbyte,
4735c4bbdfSmrg                    nmiddle, endmask, endbyte);
4805b261ecSmrg    if (startmask)
4935c4bbdfSmrg        dstStride--;
5005b261ecSmrg    dstStride -= nmiddle;
5135c4bbdfSmrg    while (height--) {
5235c4bbdfSmrg        if (startmask) {
5335c4bbdfSmrg            FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor);
5435c4bbdfSmrg            dst++;
5535c4bbdfSmrg        }
5635c4bbdfSmrg        n = nmiddle;
5735c4bbdfSmrg        if (!and)
5835c4bbdfSmrg            while (n--)
5935c4bbdfSmrg                WRITE(dst++, xor);
6035c4bbdfSmrg        else
6135c4bbdfSmrg            while (n--) {
6235c4bbdfSmrg                WRITE(dst, FbDoRRop(READ(dst), and, xor));
6305b261ecSmrg                dst++;
6435c4bbdfSmrg            }
6535c4bbdfSmrg        if (endmask)
6635c4bbdfSmrg            FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor);
6735c4bbdfSmrg        dst += dstStride;
6805b261ecSmrg    }
6905b261ecSmrg}
7005b261ecSmrg
7105b261ecSmrgvoid
7235c4bbdfSmrgfbSolid24(FbBits * dst,
7335c4bbdfSmrg          FbStride dstStride,
7435c4bbdfSmrg          int dstX, int width, int height, FbBits and, FbBits xor)
7505b261ecSmrg{
7635c4bbdfSmrg    FbBits startmask, endmask;
7735c4bbdfSmrg    FbBits xor0 = 0, xor1 = 0, xor2 = 0;
7835c4bbdfSmrg    FbBits and0 = 0, and1 = 0, and2 = 0;
7935c4bbdfSmrg    FbBits xorS = 0, andS = 0, xorE = 0, andE = 0;
8035c4bbdfSmrg    int n, nmiddle;
8135c4bbdfSmrg    int rotS, rot;
8205b261ecSmrg
8305b261ecSmrg    dst += dstX >> FB_SHIFT;
8405b261ecSmrg    dstX &= FB_MASK;
8505b261ecSmrg    /*
8605b261ecSmrg     * Rotate pixel values this far across the word to align on
8705b261ecSmrg     * screen pixel boundaries
8805b261ecSmrg     */
8935c4bbdfSmrg    rot = FbFirst24Rot(dstX);
9035c4bbdfSmrg    FbMaskBits(dstX, width, startmask, nmiddle, endmask);
9105b261ecSmrg    if (startmask)
9235c4bbdfSmrg        dstStride--;
9305b261ecSmrg    dstStride -= nmiddle;
9435c4bbdfSmrg
9505b261ecSmrg    /*
9605b261ecSmrg     * Precompute rotated versions of the rasterop values
9705b261ecSmrg     */
9805b261ecSmrg    rotS = rot;
9935c4bbdfSmrg    xor = FbRot24(xor, rotS);
10035c4bbdfSmrg    and = FbRot24(and, rotS);
10135c4bbdfSmrg    if (startmask) {
10235c4bbdfSmrg        xorS = xor;
10335c4bbdfSmrg        andS = and;
10435c4bbdfSmrg        xor = FbNext24Pix(xor);
10535c4bbdfSmrg        and = FbNext24Pix(and);
10605b261ecSmrg    }
10735c4bbdfSmrg
10835c4bbdfSmrg    if (nmiddle) {
10935c4bbdfSmrg        xor0 = xor;
11035c4bbdfSmrg        and0 = and;
11135c4bbdfSmrg        xor1 = FbNext24Pix(xor0);
11235c4bbdfSmrg        and1 = FbNext24Pix(and0);
11335c4bbdfSmrg        xor2 = FbNext24Pix(xor1);
11435c4bbdfSmrg        and2 = FbNext24Pix(and1);
11505b261ecSmrg    }
11635c4bbdfSmrg
11735c4bbdfSmrg    if (endmask) {
11835c4bbdfSmrg        switch (nmiddle % 3) {
11935c4bbdfSmrg        case 0:
12035c4bbdfSmrg            xorE = xor;
12135c4bbdfSmrg            andE = and;
12235c4bbdfSmrg            break;
12335c4bbdfSmrg        case 1:
12435c4bbdfSmrg            xorE = xor1;
12535c4bbdfSmrg            andE = and1;
12635c4bbdfSmrg            break;
12735c4bbdfSmrg        case 2:
12835c4bbdfSmrg            xorE = xor2;
12935c4bbdfSmrg            andE = and2;
13035c4bbdfSmrg            break;
13135c4bbdfSmrg        }
13205b261ecSmrg    }
13335c4bbdfSmrg
13435c4bbdfSmrg    while (height--) {
13535c4bbdfSmrg        if (startmask) {
13635c4bbdfSmrg            WRITE(dst, FbDoMaskRRop(READ(dst), andS, xorS, startmask));
13705b261ecSmrg            dst++;
13835c4bbdfSmrg        }
13935c4bbdfSmrg        n = nmiddle;
14035c4bbdfSmrg        if (!and0) {
14135c4bbdfSmrg            while (n >= 3) {
14235c4bbdfSmrg                WRITE(dst++, xor0);
14335c4bbdfSmrg                WRITE(dst++, xor1);
14435c4bbdfSmrg                WRITE(dst++, xor2);
14535c4bbdfSmrg                n -= 3;
14635c4bbdfSmrg            }
14735c4bbdfSmrg            if (n) {
14835c4bbdfSmrg                WRITE(dst++, xor0);
14935c4bbdfSmrg                n--;
15035c4bbdfSmrg                if (n) {
15135c4bbdfSmrg                    WRITE(dst++, xor1);
15235c4bbdfSmrg                }
15335c4bbdfSmrg            }
15435c4bbdfSmrg        }
15535c4bbdfSmrg        else {
15635c4bbdfSmrg            while (n >= 3) {
15735c4bbdfSmrg                WRITE(dst, FbDoRRop(READ(dst), and0, xor0));
15805b261ecSmrg                dst++;
15935c4bbdfSmrg                WRITE(dst, FbDoRRop(READ(dst), and1, xor1));
16005b261ecSmrg                dst++;
16135c4bbdfSmrg                WRITE(dst, FbDoRRop(READ(dst), and2, xor2));
16205b261ecSmrg                dst++;
16335c4bbdfSmrg                n -= 3;
16435c4bbdfSmrg            }
16535c4bbdfSmrg            if (n) {
16635c4bbdfSmrg                WRITE(dst, FbDoRRop(READ(dst), and0, xor0));
16705b261ecSmrg                dst++;
16835c4bbdfSmrg                n--;
16935c4bbdfSmrg                if (n) {
17035c4bbdfSmrg                    WRITE(dst, FbDoRRop(READ(dst), and1, xor1));
17105b261ecSmrg                    dst++;
17235c4bbdfSmrg                }
17335c4bbdfSmrg            }
17435c4bbdfSmrg        }
17535c4bbdfSmrg        if (endmask)
17635c4bbdfSmrg            WRITE(dst, FbDoMaskRRop(READ(dst), andE, xorE, endmask));
17735c4bbdfSmrg        dst += dstStride;
17805b261ecSmrg    }
17905b261ecSmrg}
180