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
39	    int		width,
40	    int		height,
41
42	    FbBits	*tile,
43	    FbStride	tileStride,
44	    int		tileHeight,
45
46	    int		alu,
47	    FbBits	pm,
48	    int		xRot,
49	    int		yRot)
50{
51    FbBits  *t, *tileEnd, bits;
52    FbBits  startmask, endmask;
53    FbBits  and, xor;
54    int	    n, nmiddle;
55    int	    tileX, tileY;
56    int	    rot;
57    int	    startbyte, endbyte;
58
59    dst += dstX >> FB_SHIFT;
60    dstX &= FB_MASK;
61    FbMaskBitsBytes(dstX, width, FbDestInvarientRop(alu, pm),
62		    startmask, startbyte, nmiddle, endmask, endbyte);
63    if (startmask)
64	dstStride--;
65    dstStride -= nmiddle;
66
67    /*
68     * Compute tile start scanline and rotation parameters
69     */
70    tileEnd = tile + tileHeight * tileStride;
71    modulus (- yRot, tileHeight, tileY);
72    t = tile + tileY * tileStride;
73    modulus (- xRot, FB_UNIT, tileX);
74    rot = tileX;
75
76    while (height--)
77    {
78
79	/*
80	 * Pick up bits for this scanline
81	 */
82	bits = READ(t);
83	t += tileStride;
84	if (t >= tileEnd) t = tile;
85	bits = FbRotLeft(bits,rot);
86	and = fbAnd(alu,bits,pm);
87	xor = fbXor(alu,bits,pm);
88
89	if (startmask)
90	{
91	    FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor);
92	    dst++;
93	}
94	n = nmiddle;
95	if (!and)
96	    while (n--)
97		WRITE(dst++, xor);
98	else
99	    while (n--)
100	    {
101		WRITE(dst, FbDoRRop (READ(dst), and, xor));
102		dst++;
103	    }
104	if (endmask)
105	    FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor);
106	dst += dstStride;
107    }
108}
109
110void
111fbOddTile(FbBits    *dst,
112	  FbStride  dstStride,
113	  int	    dstX,
114
115	  int	    width,
116	  int	    height,
117
118	  FbBits    *tile,
119	  FbStride  tileStride,
120	  int	    tileWidth,
121	  int	    tileHeight,
122
123	  int	    alu,
124	  FbBits    pm,
125	  int	    bpp,
126
127	  int	    xRot,
128	  int	    yRot)
129{
130    int	    tileX, tileY;
131    int	    widthTmp;
132    int	    h, w;
133    int	    x, y;
134
135    modulus (- yRot, tileHeight, tileY);
136    y = 0;
137    while (height)
138    {
139	h = tileHeight - tileY;
140	if (h > height)
141	    h = height;
142	height -= h;
143	widthTmp = width;
144	x = dstX;
145	modulus (dstX - xRot, tileWidth, tileX);
146	while (widthTmp)
147	{
148	    w = tileWidth - tileX;
149	    if (w > widthTmp)
150		w = widthTmp;
151	    widthTmp -= w;
152	    fbBlt (tile + tileY * tileStride,
153		   tileStride,
154		   tileX,
155
156		   dst + y * dstStride,
157		   dstStride,
158		   x,
159
160		   w, h,
161		   alu,
162		   pm,
163		   bpp,
164
165		   FALSE,
166		   FALSE);
167	    x += w;
168	    tileX = 0;
169	}
170	y += h;
171	tileY = 0;
172    }
173}
174
175void
176fbTile (FbBits	    *dst,
177	FbStride    dstStride,
178	int	    dstX,
179
180	int	    width,
181	int	    height,
182
183	FbBits	    *tile,
184	FbStride    tileStride,
185	int	    tileWidth,
186	int	    tileHeight,
187
188	int	    alu,
189	FbBits	    pm,
190	int	    bpp,
191
192	int	    xRot,
193	int	    yRot)
194{
195    if (FbEvenTile (tileWidth))
196	fbEvenTile (dst, dstStride, dstX, width, height,
197		    tile, tileStride, tileHeight,
198		    alu, pm, xRot, yRot);
199    else
200	fbOddTile (dst, dstStride, dstX, width, height,
201		   tile, tileStride, tileWidth, tileHeight,
202		   alu, pm, bpp, xRot, yRot);
203}
204