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