Imported Upstream version 1.15.1
[deb_xorg-server.git] / fb / fbtile.c
CommitLineData
a09e091a
JB
1/*
2 * Copyright © 1998 Keith Packard
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Keith Packard not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Keith Packard makes no
11 * representations about the suitability of this software for any purpose. It
12 * is provided "as is" without express or implied warranty.
13 *
14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#ifdef HAVE_DIX_CONFIG_H
24#include <dix-config.h>
25#endif
26
27#include "fb.h"
28
29/*
30 * Accelerated tile fill -- tile width is a power of two not greater
31 * than FB_UNIT
32 */
33
34void
35fbEvenTile(FbBits * dst,
36 FbStride dstStride,
37 int dstX,
38 int width,
39 int height,
40 FbBits * tile,
41 FbStride tileStride,
42 int tileHeight, int alu, FbBits pm, int xRot, int yRot)
43{
44 FbBits *t, *tileEnd, bits;
45 FbBits startmask, endmask;
46 FbBits and, xor;
47 int n, nmiddle;
48 int tileX, tileY;
49 int rot;
50 int startbyte, endbyte;
51
52 dst += dstX >> FB_SHIFT;
53 dstX &= FB_MASK;
54 FbMaskBitsBytes(dstX, width, FbDestInvarientRop(alu, pm),
55 startmask, startbyte, nmiddle, endmask, endbyte);
56 if (startmask)
57 dstStride--;
58 dstStride -= nmiddle;
59
60 /*
61 * Compute tile start scanline and rotation parameters
62 */
63 tileEnd = tile + tileHeight * tileStride;
64 modulus(-yRot, tileHeight, tileY);
65 t = tile + tileY * tileStride;
66 modulus(-xRot, FB_UNIT, tileX);
67 rot = tileX;
68
69 while (height--) {
70
71 /*
72 * Pick up bits for this scanline
73 */
74 bits = READ(t);
75 t += tileStride;
76 if (t >= tileEnd)
77 t = tile;
78 bits = FbRotLeft(bits, rot);
79 and = fbAnd(alu, bits, pm);
80 xor = fbXor(alu, bits, pm);
81
82 if (startmask) {
83 FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor);
84 dst++;
85 }
86 n = nmiddle;
87 if (!and)
88 while (n--)
89 WRITE(dst++, xor);
90 else
91 while (n--) {
92 WRITE(dst, FbDoRRop(READ(dst), and, xor));
93 dst++;
94 }
95 if (endmask)
96 FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor);
97 dst += dstStride;
98 }
99}
100
101void
102fbOddTile(FbBits * dst,
103 FbStride dstStride,
104 int dstX,
105 int width,
106 int height,
107 FbBits * tile,
108 FbStride tileStride,
109 int tileWidth,
110 int tileHeight, int alu, FbBits pm, int bpp, int xRot, int yRot)
111{
112 int tileX, tileY;
113 int widthTmp;
114 int h, w;
115 int x, y;
116
117 modulus(-yRot, tileHeight, tileY);
118 y = 0;
119 while (height) {
120 h = tileHeight - tileY;
121 if (h > height)
122 h = height;
123 height -= h;
124 widthTmp = width;
125 x = dstX;
126 modulus(dstX - xRot, tileWidth, tileX);
127 while (widthTmp) {
128 w = tileWidth - tileX;
129 if (w > widthTmp)
130 w = widthTmp;
131 widthTmp -= w;
132 fbBlt(tile + tileY * tileStride,
133 tileStride,
134 tileX,
135 dst + y * dstStride,
136 dstStride, x, w, h, alu, pm, bpp, FALSE, FALSE);
137 x += w;
138 tileX = 0;
139 }
140 y += h;
141 tileY = 0;
142 }
143}
144
145void
146fbTile(FbBits * dst,
147 FbStride dstStride,
148 int dstX,
149 int width,
150 int height,
151 FbBits * tile,
152 FbStride tileStride,
153 int tileWidth,
154 int tileHeight, int alu, FbBits pm, int bpp, int xRot, int yRot)
155{
156 if (FbEvenTile(tileWidth))
157 fbEvenTile(dst, dstStride, dstX, width, height,
158 tile, tileStride, tileHeight, alu, pm, xRot, yRot);
159 else
160 fbOddTile(dst, dstStride, dstX, width, height,
161 tile, tileStride, tileWidth, tileHeight,
162 alu, pm, bpp, xRot, yRot);
163}