Commit | Line | Data |
---|---|---|
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 | ||
34 | void | |
35 | fbEvenTile(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 | ||
101 | void | |
102 | fbOddTile(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 | ||
145 | void | |
146 | fbTile(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 | } |