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