1706f2543Smrg/*
2706f2543Smrg * Copyright © 1998 Keith Packard
3706f2543Smrg *
4706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its
5706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that
6706f2543Smrg * the above copyright notice appear in all copies and that both that
7706f2543Smrg * copyright notice and this permission notice appear in supporting
8706f2543Smrg * documentation, and that the name of Keith Packard not be used in
9706f2543Smrg * advertising or publicity pertaining to distribution of the software without
10706f2543Smrg * specific, written prior permission.  Keith Packard makes no
11706f2543Smrg * representations about the suitability of this software for any purpose.  It
12706f2543Smrg * is provided "as is" without express or implied warranty.
13706f2543Smrg *
14706f2543Smrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16706f2543Smrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20706f2543Smrg * PERFORMANCE OF THIS SOFTWARE.
21706f2543Smrg */
22706f2543Smrg
23706f2543Smrg#ifdef HAVE_DIX_CONFIG_H
24706f2543Smrg#include <dix-config.h>
25706f2543Smrg#endif
26706f2543Smrg
27706f2543Smrg#include "fb.h"
28706f2543Smrg
29706f2543Smrg/*
30706f2543Smrg * Accelerated tile fill -- tile width is a power of two not greater
31706f2543Smrg * than FB_UNIT
32706f2543Smrg */
33706f2543Smrg
34706f2543Smrgvoid
35706f2543SmrgfbEvenTile (FbBits	*dst,
36706f2543Smrg	    FbStride	dstStride,
37706f2543Smrg	    int		dstX,
38706f2543Smrg
39706f2543Smrg	    int		width,
40706f2543Smrg	    int		height,
41706f2543Smrg
42706f2543Smrg	    FbBits	*tile,
43706f2543Smrg	    FbStride	tileStride,
44706f2543Smrg	    int		tileHeight,
45706f2543Smrg
46706f2543Smrg	    int		alu,
47706f2543Smrg	    FbBits	pm,
48706f2543Smrg	    int		xRot,
49706f2543Smrg	    int		yRot)
50706f2543Smrg{
51706f2543Smrg    FbBits  *t, *tileEnd, bits;
52706f2543Smrg    FbBits  startmask, endmask;
53706f2543Smrg    FbBits  and, xor;
54706f2543Smrg    int	    n, nmiddle;
55706f2543Smrg    int	    tileX, tileY;
56706f2543Smrg    int	    rot;
57706f2543Smrg    int	    startbyte, endbyte;
58706f2543Smrg
59706f2543Smrg    dst += dstX >> FB_SHIFT;
60706f2543Smrg    dstX &= FB_MASK;
61706f2543Smrg    FbMaskBitsBytes(dstX, width, FbDestInvarientRop(alu, pm),
62706f2543Smrg		    startmask, startbyte, nmiddle, endmask, endbyte);
63706f2543Smrg    if (startmask)
64706f2543Smrg	dstStride--;
65706f2543Smrg    dstStride -= nmiddle;
66706f2543Smrg
67706f2543Smrg    /*
68706f2543Smrg     * Compute tile start scanline and rotation parameters
69706f2543Smrg     */
70706f2543Smrg    tileEnd = tile + tileHeight * tileStride;
71706f2543Smrg    modulus (- yRot, tileHeight, tileY);
72706f2543Smrg    t = tile + tileY * tileStride;
73706f2543Smrg    modulus (- xRot, FB_UNIT, tileX);
74706f2543Smrg    rot = tileX;
75706f2543Smrg
76706f2543Smrg    while (height--)
77706f2543Smrg    {
78706f2543Smrg
79706f2543Smrg	/*
80706f2543Smrg	 * Pick up bits for this scanline
81706f2543Smrg	 */
82706f2543Smrg	bits = READ(t);
83706f2543Smrg	t += tileStride;
84706f2543Smrg	if (t >= tileEnd) t = tile;
85706f2543Smrg	bits = FbRotLeft(bits,rot);
86706f2543Smrg	and = fbAnd(alu,bits,pm);
87706f2543Smrg	xor = fbXor(alu,bits,pm);
88706f2543Smrg
89706f2543Smrg	if (startmask)
90706f2543Smrg	{
91706f2543Smrg	    FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor);
92706f2543Smrg	    dst++;
93706f2543Smrg	}
94706f2543Smrg	n = nmiddle;
95706f2543Smrg	if (!and)
96706f2543Smrg	    while (n--)
97706f2543Smrg		WRITE(dst++, xor);
98706f2543Smrg	else
99706f2543Smrg	    while (n--)
100706f2543Smrg	    {
101706f2543Smrg		WRITE(dst, FbDoRRop (READ(dst), and, xor));
102706f2543Smrg		dst++;
103706f2543Smrg	    }
104706f2543Smrg	if (endmask)
105706f2543Smrg	    FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor);
106706f2543Smrg	dst += dstStride;
107706f2543Smrg    }
108706f2543Smrg}
109706f2543Smrg
110706f2543Smrgvoid
111706f2543SmrgfbOddTile(FbBits    *dst,
112706f2543Smrg	  FbStride  dstStride,
113706f2543Smrg	  int	    dstX,
114706f2543Smrg
115706f2543Smrg	  int	    width,
116706f2543Smrg	  int	    height,
117706f2543Smrg
118706f2543Smrg	  FbBits    *tile,
119706f2543Smrg	  FbStride  tileStride,
120706f2543Smrg	  int	    tileWidth,
121706f2543Smrg	  int	    tileHeight,
122706f2543Smrg
123706f2543Smrg	  int	    alu,
124706f2543Smrg	  FbBits    pm,
125706f2543Smrg	  int	    bpp,
126706f2543Smrg
127706f2543Smrg	  int	    xRot,
128706f2543Smrg	  int	    yRot)
129706f2543Smrg{
130706f2543Smrg    int	    tileX, tileY;
131706f2543Smrg    int	    widthTmp;
132706f2543Smrg    int	    h, w;
133706f2543Smrg    int	    x, y;
134706f2543Smrg
135706f2543Smrg    modulus (- yRot, tileHeight, tileY);
136706f2543Smrg    y = 0;
137706f2543Smrg    while (height)
138706f2543Smrg    {
139706f2543Smrg	h = tileHeight - tileY;
140706f2543Smrg	if (h > height)
141706f2543Smrg	    h = height;
142706f2543Smrg	height -= h;
143706f2543Smrg	widthTmp = width;
144706f2543Smrg	x = dstX;
145706f2543Smrg	modulus (dstX - xRot, tileWidth, tileX);
146706f2543Smrg	while (widthTmp)
147706f2543Smrg	{
148706f2543Smrg	    w = tileWidth - tileX;
149706f2543Smrg	    if (w > widthTmp)
150706f2543Smrg		w = widthTmp;
151706f2543Smrg	    widthTmp -= w;
152706f2543Smrg	    fbBlt (tile + tileY * tileStride,
153706f2543Smrg		   tileStride,
154706f2543Smrg		   tileX,
155706f2543Smrg
156706f2543Smrg		   dst + y * dstStride,
157706f2543Smrg		   dstStride,
158706f2543Smrg		   x,
159706f2543Smrg
160706f2543Smrg		   w, h,
161706f2543Smrg		   alu,
162706f2543Smrg		   pm,
163706f2543Smrg		   bpp,
164706f2543Smrg
165706f2543Smrg		   FALSE,
166706f2543Smrg		   FALSE);
167706f2543Smrg	    x += w;
168706f2543Smrg	    tileX = 0;
169706f2543Smrg	}
170706f2543Smrg	y += h;
171706f2543Smrg	tileY = 0;
172706f2543Smrg    }
173706f2543Smrg}
174706f2543Smrg
175706f2543Smrgvoid
176706f2543SmrgfbTile (FbBits	    *dst,
177706f2543Smrg	FbStride    dstStride,
178706f2543Smrg	int	    dstX,
179706f2543Smrg
180706f2543Smrg	int	    width,
181706f2543Smrg	int	    height,
182706f2543Smrg
183706f2543Smrg	FbBits	    *tile,
184706f2543Smrg	FbStride    tileStride,
185706f2543Smrg	int	    tileWidth,
186706f2543Smrg	int	    tileHeight,
187706f2543Smrg
188706f2543Smrg	int	    alu,
189706f2543Smrg	FbBits	    pm,
190706f2543Smrg	int	    bpp,
191706f2543Smrg
192706f2543Smrg	int	    xRot,
193706f2543Smrg	int	    yRot)
194706f2543Smrg{
195706f2543Smrg    if (FbEvenTile (tileWidth))
196706f2543Smrg	fbEvenTile (dst, dstStride, dstX, width, height,
197706f2543Smrg		    tile, tileStride, tileHeight,
198706f2543Smrg		    alu, pm, xRot, yRot);
199706f2543Smrg    else
200706f2543Smrg	fbOddTile (dst, dstStride, dstX, width, height,
201706f2543Smrg		   tile, tileStride, tileWidth, tileHeight,
202706f2543Smrg		   alu, pm, bpp, xRot, yRot);
203706f2543Smrg}
204