1428d7b3dSmrg/*
2428d7b3dSmrg * Copyright © 1998 Keith Packard
3428d7b3dSmrg * Copyright © 2012 Intel Corporation
4428d7b3dSmrg *
5428d7b3dSmrg * Permission to use, copy, modify, distribute, and sell this software and its
6428d7b3dSmrg * documentation for any purpose is hereby granted without fee, provided that
7428d7b3dSmrg * the above copyright notice appear in all copies and that both that
8428d7b3dSmrg * copyright notice and this permission notice appear in supporting
9428d7b3dSmrg * documentation, and that the name of Keith Packard not be used in
10428d7b3dSmrg * advertising or publicity pertaining to distribution of the software without
11428d7b3dSmrg * specific, written prior permission.  Keith Packard makes no
12428d7b3dSmrg * representations about the suitability of this software for any purpose.  It
13428d7b3dSmrg * is provided "as is" without express or implied warranty.
14428d7b3dSmrg *
15428d7b3dSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16428d7b3dSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17428d7b3dSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18428d7b3dSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19428d7b3dSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20428d7b3dSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21428d7b3dSmrg * PERFORMANCE OF THIS SOFTWARE.
22428d7b3dSmrg */
23428d7b3dSmrg
24428d7b3dSmrg#include "fb.h"
25428d7b3dSmrg
26428d7b3dSmrg/*
27428d7b3dSmrg * Accelerated tile fill -- tile width is a power of two not greater
28428d7b3dSmrg * than FB_UNIT
29428d7b3dSmrg */
30428d7b3dSmrg
31428d7b3dSmrgstatic void
32428d7b3dSmrgfbEvenTile(FbBits *dst, FbStride dstStride, int dstX, int width, int height,
33428d7b3dSmrg           FbBits *tile, FbStride tileStride, int tileHeight,
34428d7b3dSmrg	   int alu, FbBits pm,
35428d7b3dSmrg	   int xRot, int yRot)
36428d7b3dSmrg{
37428d7b3dSmrg	FbBits *t, *tileEnd, bits;
38428d7b3dSmrg	FbBits startmask, endmask;
39428d7b3dSmrg	FbBits and, xor;
40428d7b3dSmrg	int n, nmiddle;
41428d7b3dSmrg	int tileX, tileY;
42428d7b3dSmrg	int rot;
43428d7b3dSmrg	int startbyte, endbyte;
44428d7b3dSmrg
45428d7b3dSmrg	dst += dstX >> FB_SHIFT;
46428d7b3dSmrg	dstX &= FB_MASK;
47428d7b3dSmrg	FbMaskBitsBytes(dstX, width, FbDestInvarientRop(alu, pm),
48428d7b3dSmrg			startmask, startbyte, nmiddle, endmask, endbyte);
49428d7b3dSmrg	if (startmask)
50428d7b3dSmrg		dstStride--;
51428d7b3dSmrg	dstStride -= nmiddle;
52428d7b3dSmrg
53428d7b3dSmrg	/*
54428d7b3dSmrg	 * Compute tile start scanline and rotation parameters
55428d7b3dSmrg	 */
56428d7b3dSmrg	tileEnd = tile + tileHeight * tileStride;
57428d7b3dSmrg	modulus(-yRot, tileHeight, tileY);
58428d7b3dSmrg	t = tile + tileY * tileStride;
59428d7b3dSmrg	modulus(-xRot, FB_UNIT, tileX);
60428d7b3dSmrg	rot = tileX;
61428d7b3dSmrg
62428d7b3dSmrg	while (height--) {
63428d7b3dSmrg		/*
64428d7b3dSmrg		 * Pick up bits for this scanline
65428d7b3dSmrg		 */
66428d7b3dSmrg		bits = READ(t);
67428d7b3dSmrg		t += tileStride;
68428d7b3dSmrg		if (t >= tileEnd)
69428d7b3dSmrg			t = tile;
70428d7b3dSmrg		bits = FbRotLeft(bits, rot);
71428d7b3dSmrg		and = fbAnd(alu, bits, pm);
72428d7b3dSmrg		xor = fbXor(alu, bits, pm);
73428d7b3dSmrg
74428d7b3dSmrg		if (startmask) {
75428d7b3dSmrg			FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor);
76428d7b3dSmrg			dst++;
77428d7b3dSmrg		}
78428d7b3dSmrg		n = nmiddle;
79428d7b3dSmrg		if (!and)
80428d7b3dSmrg			while (n--)
81428d7b3dSmrg				WRITE(dst++, xor);
82428d7b3dSmrg		else
83428d7b3dSmrg			while (n--) {
84428d7b3dSmrg				WRITE(dst, FbDoRRop(READ(dst), and, xor));
85428d7b3dSmrg				dst++;
86428d7b3dSmrg			}
87428d7b3dSmrg		if (endmask)
88428d7b3dSmrg			FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor);
89428d7b3dSmrg		dst += dstStride;
90428d7b3dSmrg	}
91428d7b3dSmrg}
92428d7b3dSmrg
93428d7b3dSmrgstatic void
94428d7b3dSmrgfbOddTile(FbBits *dst, FbStride dstStride, int dstX,
95428d7b3dSmrg          int width, int height,
96428d7b3dSmrg          FbBits *tile, FbStride tileStride,
97428d7b3dSmrg          int tileWidth, int tileHeight,
98428d7b3dSmrg	  int alu, FbBits pm, int bpp,
99428d7b3dSmrg	  int xRot, int yRot)
100428d7b3dSmrg{
101428d7b3dSmrg	int tileX, tileY;
102428d7b3dSmrg	int x, y;
103428d7b3dSmrg
104428d7b3dSmrg	DBG(("%s tile=%dx%d, size=%dx%d\n", __FUNCTION__,
105428d7b3dSmrg	     tileWidth, tileHeight, width, height));
106428d7b3dSmrg
107428d7b3dSmrg	modulus(-yRot, tileHeight, tileY);
108428d7b3dSmrg	y = 0;
109428d7b3dSmrg	while (height) {
110428d7b3dSmrg		int ww = width;
111428d7b3dSmrg		int h = tileHeight - tileY;
112428d7b3dSmrg		if (h > height)
113428d7b3dSmrg			h = height;
114428d7b3dSmrg		height -= h;
115428d7b3dSmrg		x = dstX;
116428d7b3dSmrg		modulus(dstX - xRot, tileWidth, tileX);
117428d7b3dSmrg		while (ww) {
118428d7b3dSmrg			int w = tileWidth - tileX;
119428d7b3dSmrg			if (w > ww)
120428d7b3dSmrg				w = ww;
121428d7b3dSmrg			ww -= w;
122428d7b3dSmrg			fbBlt(tile + tileY * tileStride, tileStride, tileX,
123428d7b3dSmrg			      dst + y * dstStride, dstStride,
124428d7b3dSmrg			      x, w, h, alu, pm, bpp, FALSE, FALSE);
125428d7b3dSmrg			x += w;
126428d7b3dSmrg			tileX = 0;
127428d7b3dSmrg		}
128428d7b3dSmrg		y += h;
129428d7b3dSmrg		tileY = 0;
130428d7b3dSmrg	}
131428d7b3dSmrg}
132428d7b3dSmrg
133428d7b3dSmrgvoid
134428d7b3dSmrgfbTile(FbBits *dst, FbStride dstStride, int dstX,
135428d7b3dSmrg       int width, int height,
136428d7b3dSmrg       FbBits *tile, FbStride tileStride,
137428d7b3dSmrg       int tileWidth, int tileHeight,
138428d7b3dSmrg       int alu, FbBits pm, int bpp,
139428d7b3dSmrg       int xRot, int yRot)
140428d7b3dSmrg{
141428d7b3dSmrg	DBG(("%s tile=%dx%d, size=%dx%d\n", __FUNCTION__,
142428d7b3dSmrg	     tileWidth, tileHeight, width, height));
143428d7b3dSmrg
144428d7b3dSmrg	if (FbEvenTile(tileWidth))
145428d7b3dSmrg		fbEvenTile(dst, dstStride, dstX, width, height,
146428d7b3dSmrg			   tile, tileStride, tileHeight, alu, pm, xRot, yRot);
147428d7b3dSmrg	else
148428d7b3dSmrg		fbOddTile(dst, dstStride, dstX, width, height,
149428d7b3dSmrg			  tile, tileStride, tileWidth, tileHeight,
150428d7b3dSmrg			  alu, pm, bpp, xRot, yRot);
151428d7b3dSmrg}
152