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, shadowBufPtr pBuf) 91{ 92 RegionPtr damage = DamageRegion(pBuf->pDamage); 93 PixmapPtr pShadow = pBuf->pPixmap; 94 int nbox = RegionNumRects(damage); 95 BoxPtr pbox = RegionRects(damage); 96 CARD32 *shaBase, *shaLine, *sha; 97 FbStride shaStride; 98 int scrBase, scrLine, scr; 99 int shaBpp; 100 _X_UNUSED int shaXoff, shaYoff; 101 int x, y, w, h, width; 102 int i; 103 CARD32 *winBase = NULL, *win; 104 CARD32 winSize; 105 int plane; 106 CARD32 m, m5, m6; 107 CARD8 s1, s2, s3, s4; 108 109 fbGetStipDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, 110 shaYoff); 111 while (nbox--) { 112 x = (pbox->x1) * shaBpp; 113 y = (pbox->y1); 114 w = (pbox->x2 - pbox->x1) * shaBpp; 115 h = pbox->y2 - pbox->y1; 116 117 w = (w + (x & PL_MASK) + PL_MASK) >> PL_SHIFT; 118 x &= ~PL_MASK; 119 120 scrLine = (x >> PL_SHIFT); 121 shaLine = shaBase + y * shaStride + (x >> FB_SHIFT); 122 123 while (h--) { 124 for (plane = 0; plane < 4; plane++) { 125 width = w; 126 scr = scrLine; 127 sha = shaLine; 128 winSize = 0; 129 scrBase = 0; 130 while (width) { 131 /* how much remains in this window */ 132 i = scrBase + winSize - scr; 133 if (i <= 0 || scr < scrBase) { 134 winBase = (CARD32 *) (*pBuf->window) (pScreen, 135 y, 136 (scr << 4) | 137 (plane), 138 SHADOW_WINDOW_WRITE, 139 &winSize, 140 pBuf->closure); 141 if (!winBase) 142 return; 143 winSize >>= 2; 144 scrBase = scr; 145 i = winSize; 146 } 147 win = winBase + (scr - scrBase); 148 if (i > width) 149 i = width; 150 width -= i; 151 scr += i; 152 153 while (i--) { 154 GetBits(plane, 0, s1); 155 GetBits(plane, 1, s2); 156 GetBits(plane, 2, s3); 157 GetBits(plane, 3, s4); 158 *win++ = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); 159 sha += 4; 160 } 161 } 162 } 163 shaLine += shaStride; 164 y++; 165 } 166 pbox++; 167 } 168} 169