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