11b5d61b8Smrg/* 21b5d61b8Smrg * Copyright © 2000 Keith Packard 31b5d61b8Smrg * 41b5d61b8Smrg * Permission to use, copy, modify, distribute, and sell this software and its 51b5d61b8Smrg * documentation for any purpose is hereby granted without fee, provided that 61b5d61b8Smrg * the above copyright notice appear in all copies and that both that 71b5d61b8Smrg * copyright notice and this permission notice appear in supporting 81b5d61b8Smrg * documentation, and that the name of Keith Packard not be used in 91b5d61b8Smrg * advertising or publicity pertaining to distribution of the software without 101b5d61b8Smrg * specific, written prior permission. Keith Packard makes no 111b5d61b8Smrg * representations about the suitability of this software for any purpose. It 121b5d61b8Smrg * is provided "as is" without express or implied warranty. 131b5d61b8Smrg * 141b5d61b8Smrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 151b5d61b8Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 161b5d61b8Smrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 171b5d61b8Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 181b5d61b8Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 191b5d61b8Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 201b5d61b8Smrg * PERFORMANCE OF THIS SOFTWARE. 211b5d61b8Smrg */ 221b5d61b8Smrg 231b5d61b8Smrg#ifdef HAVE_DIX_CONFIG_H 241b5d61b8Smrg#include "dix-config.h" 251b5d61b8Smrg#endif 261b5d61b8Smrg 271b5d61b8Smrg#include "shadow.h" 281b5d61b8Smrg#include "fb.h" 291b5d61b8Smrg 301b5d61b8Smrg#define Get8(a) ((CARD32) READ(a)) 311b5d61b8Smrg 321b5d61b8Smrg#if BITMAP_BIT_ORDER == MSBFirst 331b5d61b8Smrg#define Get24(a) ((Get8(a) << 16) | (Get8((a)+1) << 8) | Get8((a)+2)) 341b5d61b8Smrg#define Put24(a,p) ((WRITE((a+0), (CARD8) ((p) >> 16))), \ 351b5d61b8Smrg (WRITE((a+1), (CARD8) ((p) >> 8))), \ 361b5d61b8Smrg (WRITE((a+2), (CARD8) (p)))) 371b5d61b8Smrg#else 381b5d61b8Smrg#define Get24(a) (Get8(a) | (Get8((a)+1) << 8) | (Get8((a)+2)<<16)) 391b5d61b8Smrg#define Put24(a,p) ((WRITE((a+0), (CARD8) (p))), \ 401b5d61b8Smrg (WRITE((a+1), (CARD8) ((p) >> 8))), \ 411b5d61b8Smrg (WRITE((a+2), (CARD8) ((p) >> 16)))) 421b5d61b8Smrg#endif 431b5d61b8Smrg 441b5d61b8Smrgstatic void 451b5d61b8Smrgsh24_32BltLine(CARD8 *srcLine, 461b5d61b8Smrg CARD8 *dstLine, 471b5d61b8Smrg int width) 481b5d61b8Smrg{ 491b5d61b8Smrg CARD32 *src; 501b5d61b8Smrg CARD8 *dst; 511b5d61b8Smrg int w; 521b5d61b8Smrg CARD32 pixel; 531b5d61b8Smrg 541b5d61b8Smrg src = (CARD32 *) srcLine; 551b5d61b8Smrg dst = dstLine; 561b5d61b8Smrg w = width; 571b5d61b8Smrg 581b5d61b8Smrg while (((long)dst & 3) && w) { 591b5d61b8Smrg w--; 601b5d61b8Smrg pixel = READ(src++); 611b5d61b8Smrg Put24(dst, pixel); 621b5d61b8Smrg dst += 3; 631b5d61b8Smrg } 641b5d61b8Smrg /* Do four aligned pixels at a time */ 651b5d61b8Smrg while (w >= 4) { 661b5d61b8Smrg CARD32 s0, s1; 671b5d61b8Smrg 681b5d61b8Smrg s0 = READ(src++); 691b5d61b8Smrg s1 = READ(src++); 701b5d61b8Smrg#if BITMAP_BIT_ORDER == LSBFirst 711b5d61b8Smrg WRITE((CARD32 *) dst, (s0 & 0xffffff) | (s1 << 24)); 721b5d61b8Smrg#else 731b5d61b8Smrg WRITE((CARD32 *) dst, (s0 << 8) | ((s1 & 0xffffff) >> 16)); 741b5d61b8Smrg#endif 751b5d61b8Smrg s0 = READ(src++); 761b5d61b8Smrg#if BITMAP_BIT_ORDER == LSBFirst 771b5d61b8Smrg WRITE((CARD32 *) (dst + 4), 781b5d61b8Smrg ((s1 & 0xffffff) >> 8) | (s0 << 16)); 791b5d61b8Smrg#else 801b5d61b8Smrg WRITE((CARD32 *) (dst + 4), 811b5d61b8Smrg (s1 << 16) | ((s0 & 0xffffff) >> 8)); 821b5d61b8Smrg#endif 831b5d61b8Smrg s1 = READ(src++); 841b5d61b8Smrg#if BITMAP_BIT_ORDER == LSBFirst 851b5d61b8Smrg WRITE((CARD32 *) (dst + 8), 861b5d61b8Smrg ((s0 & 0xffffff) >> 16) | (s1 << 8)); 871b5d61b8Smrg#else 881b5d61b8Smrg WRITE((CARD32 *) (dst + 8), (s0 << 24) | (s1 & 0xffffff)); 891b5d61b8Smrg#endif 901b5d61b8Smrg dst += 12; 911b5d61b8Smrg w -= 4; 921b5d61b8Smrg } 931b5d61b8Smrg while (w--) { 941b5d61b8Smrg pixel = READ(src++); 951b5d61b8Smrg Put24(dst, pixel); 961b5d61b8Smrg dst += 3; 971b5d61b8Smrg } 981b5d61b8Smrg} 991b5d61b8Smrg 1001b5d61b8Smrgvoid 1011b5d61b8SmrgshadowUpdate32to24(ScreenPtr pScreen, shadowBufPtr pBuf) 1021b5d61b8Smrg{ 1031b5d61b8Smrg RegionPtr damage = DamageRegion(pBuf->pDamage); 1041b5d61b8Smrg PixmapPtr pShadow = pBuf->pPixmap; 1051b5d61b8Smrg int nbox = RegionNumRects(damage); 1061b5d61b8Smrg BoxPtr pbox = RegionRects(damage); 1071b5d61b8Smrg FbStride shaStride; 1081b5d61b8Smrg int shaBpp; 1091b5d61b8Smrg _X_UNUSED int shaXoff, shaYoff; 1101b5d61b8Smrg int x, y, w, h; 1111b5d61b8Smrg CARD32 winSize; 1121b5d61b8Smrg FbBits *shaBase, *shaLine; 1131b5d61b8Smrg CARD8 *winBase = NULL, *winLine; 1141b5d61b8Smrg 1151b5d61b8Smrg fbGetDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, 1161b5d61b8Smrg shaYoff); 1171b5d61b8Smrg 1181b5d61b8Smrg /* just get the initial window base + stride */ 1191b5d61b8Smrg winBase = (*pBuf->window)(pScreen, 0, 0, SHADOW_WINDOW_WRITE, 1201b5d61b8Smrg &winSize, pBuf->closure); 1211b5d61b8Smrg 1221b5d61b8Smrg while (nbox--) { 1231b5d61b8Smrg x = pbox->x1; 1241b5d61b8Smrg y = pbox->y1; 1251b5d61b8Smrg w = pbox->x2 - pbox->x1; 1261b5d61b8Smrg h = pbox->y2 - pbox->y1; 1271b5d61b8Smrg 1281b5d61b8Smrg winLine = winBase + y * winSize + (x * 3); 1291b5d61b8Smrg shaLine = shaBase + y * shaStride + ((x * shaBpp) >> FB_SHIFT); 1301b5d61b8Smrg 1311b5d61b8Smrg while (h--) { 1321b5d61b8Smrg sh24_32BltLine((CARD8 *)shaLine, (CARD8 *)winLine, w); 1331b5d61b8Smrg winLine += winSize; 1341b5d61b8Smrg shaLine += shaStride; 1351b5d61b8Smrg } 1361b5d61b8Smrg pbox++; 1371b5d61b8Smrg } 1381b5d61b8Smrg} 139