103b705cfSriastradh/*
203b705cfSriastradh * Copyright © 1998 Keith Packard
303b705cfSriastradh * Copyright © 2012 Intel Corporation
403b705cfSriastradh *
503b705cfSriastradh * Permission to use, copy, modify, distribute, and sell this software and its
603b705cfSriastradh * documentation for any purpose is hereby granted without fee, provided that
703b705cfSriastradh * the above copyright notice appear in all copies and that both that
803b705cfSriastradh * copyright notice and this permission notice appear in supporting
903b705cfSriastradh * documentation, and that the name of Keith Packard not be used in
1003b705cfSriastradh * advertising or publicity pertaining to distribution of the software without
1103b705cfSriastradh * specific, written prior permission.  Keith Packard makes no
1203b705cfSriastradh * representations about the suitability of this software for any purpose.  It
1303b705cfSriastradh * is provided "as is" without express or implied warranty.
1403b705cfSriastradh *
1503b705cfSriastradh * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1603b705cfSriastradh * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
1703b705cfSriastradh * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1803b705cfSriastradh * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
1903b705cfSriastradh * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
2003b705cfSriastradh * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2103b705cfSriastradh * PERFORMANCE OF THIS SOFTWARE.
2203b705cfSriastradh */
2303b705cfSriastradh
2403b705cfSriastradh#include "fb.h"
2503b705cfSriastradh
2603b705cfSriastradh/*
2703b705cfSriastradh * Accelerated tile fill -- tile width is a power of two not greater
2803b705cfSriastradh * than FB_UNIT
2903b705cfSriastradh */
3003b705cfSriastradh
3103b705cfSriastradhstatic void
3203b705cfSriastradhfbEvenTile(FbBits *dst, FbStride dstStride, int dstX, int width, int height,
3303b705cfSriastradh           FbBits *tile, FbStride tileStride, int tileHeight,
3403b705cfSriastradh	   int alu, FbBits pm,
3503b705cfSriastradh	   int xRot, int yRot)
3603b705cfSriastradh{
3703b705cfSriastradh	FbBits *t, *tileEnd, bits;
3803b705cfSriastradh	FbBits startmask, endmask;
3903b705cfSriastradh	FbBits and, xor;
4003b705cfSriastradh	int n, nmiddle;
4103b705cfSriastradh	int tileX, tileY;
4203b705cfSriastradh	int rot;
4303b705cfSriastradh	int startbyte, endbyte;
4403b705cfSriastradh
4503b705cfSriastradh	dst += dstX >> FB_SHIFT;
4603b705cfSriastradh	dstX &= FB_MASK;
4703b705cfSriastradh	FbMaskBitsBytes(dstX, width, FbDestInvarientRop(alu, pm),
4803b705cfSriastradh			startmask, startbyte, nmiddle, endmask, endbyte);
4903b705cfSriastradh	if (startmask)
5003b705cfSriastradh		dstStride--;
5103b705cfSriastradh	dstStride -= nmiddle;
5203b705cfSriastradh
5303b705cfSriastradh	/*
5403b705cfSriastradh	 * Compute tile start scanline and rotation parameters
5503b705cfSriastradh	 */
5603b705cfSriastradh	tileEnd = tile + tileHeight * tileStride;
5703b705cfSriastradh	modulus(-yRot, tileHeight, tileY);
5803b705cfSriastradh	t = tile + tileY * tileStride;
5903b705cfSriastradh	modulus(-xRot, FB_UNIT, tileX);
6003b705cfSriastradh	rot = tileX;
6103b705cfSriastradh
6203b705cfSriastradh	while (height--) {
6303b705cfSriastradh		/*
6403b705cfSriastradh		 * Pick up bits for this scanline
6503b705cfSriastradh		 */
6603b705cfSriastradh		bits = READ(t);
6703b705cfSriastradh		t += tileStride;
6803b705cfSriastradh		if (t >= tileEnd)
6903b705cfSriastradh			t = tile;
7003b705cfSriastradh		bits = FbRotLeft(bits, rot);
7103b705cfSriastradh		and = fbAnd(alu, bits, pm);
7203b705cfSriastradh		xor = fbXor(alu, bits, pm);
7303b705cfSriastradh
7403b705cfSriastradh		if (startmask) {
7503b705cfSriastradh			FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor);
7603b705cfSriastradh			dst++;
7703b705cfSriastradh		}
7803b705cfSriastradh		n = nmiddle;
7903b705cfSriastradh		if (!and)
8003b705cfSriastradh			while (n--)
8103b705cfSriastradh				WRITE(dst++, xor);
8203b705cfSriastradh		else
8303b705cfSriastradh			while (n--) {
8403b705cfSriastradh				WRITE(dst, FbDoRRop(READ(dst), and, xor));
8503b705cfSriastradh				dst++;
8603b705cfSriastradh			}
8703b705cfSriastradh		if (endmask)
8803b705cfSriastradh			FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor);
8903b705cfSriastradh		dst += dstStride;
9003b705cfSriastradh	}
9103b705cfSriastradh}
9203b705cfSriastradh
9303b705cfSriastradhstatic void
9403b705cfSriastradhfbOddTile(FbBits *dst, FbStride dstStride, int dstX,
9503b705cfSriastradh          int width, int height,
9603b705cfSriastradh          FbBits *tile, FbStride tileStride,
9703b705cfSriastradh          int tileWidth, int tileHeight,
9803b705cfSriastradh	  int alu, FbBits pm, int bpp,
9903b705cfSriastradh	  int xRot, int yRot)
10003b705cfSriastradh{
10103b705cfSriastradh	int tileX, tileY;
10203b705cfSriastradh	int x, y;
10303b705cfSriastradh
10403b705cfSriastradh	DBG(("%s tile=%dx%d, size=%dx%d\n", __FUNCTION__,
10503b705cfSriastradh	     tileWidth, tileHeight, width, height));
10603b705cfSriastradh
10703b705cfSriastradh	modulus(-yRot, tileHeight, tileY);
10803b705cfSriastradh	y = 0;
10903b705cfSriastradh	while (height) {
11003b705cfSriastradh		int ww = width;
11103b705cfSriastradh		int h = tileHeight - tileY;
11203b705cfSriastradh		if (h > height)
11303b705cfSriastradh			h = height;
11403b705cfSriastradh		height -= h;
11503b705cfSriastradh		x = dstX;
11603b705cfSriastradh		modulus(dstX - xRot, tileWidth, tileX);
11703b705cfSriastradh		while (ww) {
11803b705cfSriastradh			int w = tileWidth - tileX;
11903b705cfSriastradh			if (w > ww)
12003b705cfSriastradh				w = ww;
12103b705cfSriastradh			ww -= w;
12203b705cfSriastradh			fbBlt(tile + tileY * tileStride, tileStride, tileX,
12303b705cfSriastradh			      dst + y * dstStride, dstStride,
12403b705cfSriastradh			      x, w, h, alu, pm, bpp, FALSE, FALSE);
12503b705cfSriastradh			x += w;
12603b705cfSriastradh			tileX = 0;
12703b705cfSriastradh		}
12803b705cfSriastradh		y += h;
12903b705cfSriastradh		tileY = 0;
13003b705cfSriastradh	}
13103b705cfSriastradh}
13203b705cfSriastradh
13303b705cfSriastradhvoid
13403b705cfSriastradhfbTile(FbBits *dst, FbStride dstStride, int dstX,
13503b705cfSriastradh       int width, int height,
13603b705cfSriastradh       FbBits *tile, FbStride tileStride,
13703b705cfSriastradh       int tileWidth, int tileHeight,
13803b705cfSriastradh       int alu, FbBits pm, int bpp,
13903b705cfSriastradh       int xRot, int yRot)
14003b705cfSriastradh{
14103b705cfSriastradh	DBG(("%s tile=%dx%d, size=%dx%d\n", __FUNCTION__,
14203b705cfSriastradh	     tileWidth, tileHeight, width, height));
14303b705cfSriastradh
14403b705cfSriastradh	if (FbEvenTile(tileWidth))
14503b705cfSriastradh		fbEvenTile(dst, dstStride, dstX, width, height,
14603b705cfSriastradh			   tile, tileStride, tileHeight, alu, pm, xRot, yRot);
14703b705cfSriastradh	else
14803b705cfSriastradh		fbOddTile(dst, dstStride, dstX, width, height,
14903b705cfSriastradh			  tile, tileStride, tileWidth, tileHeight,
15003b705cfSriastradh			  alu, pm, bpp, xRot, yRot);
15103b705cfSriastradh}
152