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