1/* 2 * 3 * Copyright © 2000 Keith Packard 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#ifdef HAVE_DIX_CONFIG_H 25#include <dix-config.h> 26#endif 27 28#include <stdlib.h> 29 30#include <X11/X.h> 31#include "scrnintstr.h" 32#include "windowstr.h" 33#include <X11/fonts/font.h> 34#include "dixfontstr.h" 35#include <X11/fonts/fontstruct.h> 36#include "mi.h" 37#include "regionstr.h" 38#include "globals.h" 39#include "gcstruct.h" 40#include "shadow.h" 41#include "fb.h" 42 43/* 44 * 32 4-bit pixels per write 45 */ 46 47#define PL_SHIFT 7 48#define PL_UNIT (1 << PL_SHIFT) 49#define PL_MASK (PL_UNIT - 1) 50 51/* 52 * 32->8 conversion: 53 * 54 * 7 6 5 4 3 2 1 0 55 * A B C D E F G H 56 * 57 * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 58 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 59 * m . . . H . . . G . . . F . . . E . . . D . . . C . . . B . . . A 60 * m1 G . . . F . . . E . . . D . . . C . . . B . . . A . . . . . . . m << (7 - (p)) 61 * m2 . H . . . G . . . F . . . E . . . D . . . C . . . B . . . A . . (m >> (p)) << 2 62 * m3 G E C A m1 & 0x80808080 63 * m4 H F D B m2 & 0x40404040 64 * m5 G H E F C D A B m3 | m4 65 * m6 G H E F C D G H A B E F m5 | (m5 >> 20) 66 * m7 G H E F C D G H A B C D E F G H m6 | (m6 >> 10) 67 */ 68 69#if 0 70#define GetBits(p,o,d) {\ 71 m = sha[o]; \ 72 m1 = m << (7 - (p)); \ 73 m2 = (m >> (p)) << 2; \ 74 m3 = m1 & 0x80808080; \ 75 m4 = m2 & 0x40404040; \ 76 m5 = m3 | m4; \ 77 m6 = m5 | (m5 >> 20); \ 78 d = m6 | (m6 >> 10); \ 79} 80#else 81#define GetBits(p,o,d) {\ 82 m = sha[o]; \ 83 m5 = ((m << (7 - (p))) & 0x80808080) | (((m >> (p)) << 2) & 0x40404040); \ 84 m6 = m5 | (m5 >> 20); \ 85 d = m6 | (m6 >> 10); \ 86} 87#endif 88 89void 90shadowUpdatePlanar4 (ScreenPtr pScreen, 91 shadowBufPtr pBuf) 92{ 93 RegionPtr damage = shadowDamage (pBuf); 94 PixmapPtr pShadow = pBuf->pPixmap; 95 int nbox = RegionNumRects (damage); 96 BoxPtr pbox = RegionRects (damage); 97 CARD32 *shaBase, *shaLine, *sha; 98 FbStride shaStride; 99 int scrBase, scrLine, scr; 100 int shaBpp; 101 int shaXoff, shaYoff; /* XXX assumed to be zero */ 102 int x, y, w, h, width; 103 int i; 104 CARD32 *winBase = NULL, *win; 105 CARD32 winSize; 106 int plane; 107 CARD32 m,m5,m6; 108 CARD8 s1, s2, s3, s4; 109 110 fbGetStipDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff); 111 while (nbox--) 112 { 113 x = (pbox->x1) * shaBpp; 114 y = (pbox->y1); 115 w = (pbox->x2 - pbox->x1) * shaBpp; 116 h = pbox->y2 - pbox->y1; 117 118 w = (w + (x & PL_MASK) + PL_MASK) >> PL_SHIFT; 119 x &= ~PL_MASK; 120 121 scrLine = (x >> PL_SHIFT); 122 shaLine = shaBase + y * shaStride + (x >> FB_SHIFT); 123 124 while (h--) 125 { 126 for (plane = 0; plane < 4; plane++) 127 { 128 width = w; 129 scr = scrLine; 130 sha = shaLine; 131 winSize = 0; 132 scrBase = 0; 133 while (width) { 134 /* how much remains in this window */ 135 i = scrBase + winSize - scr; 136 if (i <= 0 || scr < scrBase) 137 { 138 winBase = (CARD32 *) (*pBuf->window) (pScreen, 139 y, 140 (scr << 4) | (plane), 141 SHADOW_WINDOW_WRITE, 142 &winSize, 143 pBuf->closure); 144 if(!winBase) 145 return; 146 winSize >>= 2; 147 scrBase = scr; 148 i = winSize; 149 } 150 win = winBase + (scr - scrBase); 151 if (i > width) 152 i = width; 153 width -= i; 154 scr += i; 155 156 while (i--) 157 { 158 GetBits(plane,0,s1); 159 GetBits(plane,1,s2); 160 GetBits(plane,2,s3); 161 GetBits(plane,3,s4); 162 *win++ = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); 163 sha += 4; 164 } 165 } 166 } 167 shaLine += shaStride; 168 y++; 169 } 170 pbox++; 171 } 172} 173 174shadowUpdateProc shadowUpdatePlanar4Weak(void) { 175 return shadowUpdatePlanar4; 176} 177 178shadowUpdateProc shadowUpdatePlanar4x8Weak(void) { 179 return shadowUpdatePlanar4x8; 180} 181