105b261ecSmrg/*
205b261ecSmrg * Copyright © 2004 Philip Blundell
305b261ecSmrg *
405b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its
505b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that
605b261ecSmrg * the above copyright notice appear in all copies and that both that
705b261ecSmrg * copyright notice and this permission notice appear in supporting
805b261ecSmrg * documentation, and that the name of Philip Blundell not be used in
905b261ecSmrg * advertising or publicity pertaining to distribution of the software without
1005b261ecSmrg * specific, written prior permission.  Philip Blundell makes no
1105b261ecSmrg * representations about the suitability of this software for any purpose.  It
1205b261ecSmrg * is provided "as is" without express or implied warranty.
1305b261ecSmrg *
1405b261ecSmrg * PHILIP BLUNDELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1505b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
1605b261ecSmrg * EVENT SHALL PHILIP BLUNDELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1705b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
1805b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
1905b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2005b261ecSmrg * PERFORMANCE OF THIS SOFTWARE.
2105b261ecSmrg */
2205b261ecSmrg
2305b261ecSmrg#include    <X11/X.h>
2405b261ecSmrg#include    "scrnintstr.h"
2505b261ecSmrg#include    "windowstr.h"
2605b261ecSmrg#include    "dixfontstr.h"
2705b261ecSmrg#include    "mi.h"
2805b261ecSmrg#include    "regionstr.h"
2905b261ecSmrg#include    "globals.h"
3005b261ecSmrg#include    "gcstruct.h"
3105b261ecSmrg#include    "shadow.h"
3205b261ecSmrg#include    "fb.h"
3305b261ecSmrg
3405b261ecSmrg#if ROTATE == 270
3505b261ecSmrg
3605b261ecSmrg#define WINSTEPX(stride)    (stride)
3705b261ecSmrg#define WINSTART(x,y)       (((pScreen->height - 1) - y) + (x * winStride))
3805b261ecSmrg#define WINSTEPY()	    -1
3905b261ecSmrg
4005b261ecSmrg#elif ROTATE == 90
4105b261ecSmrg
4205b261ecSmrg#define WINSTEPX(stride)    (-stride)
4305b261ecSmrg#define WINSTEPY()	    1
4405b261ecSmrg#define WINSTART(x,y)       (((pScreen->width - 1 - x) * winStride) + y)
4505b261ecSmrg
4605b261ecSmrg#else
4705b261ecSmrg
4805b261ecSmrg#error This rotation is not supported here
4905b261ecSmrg
5005b261ecSmrg#endif
5105b261ecSmrg
5205b261ecSmrg#ifdef __arm__
5305b261ecSmrg#define PREFETCH
5405b261ecSmrg#endif
5505b261ecSmrg
5605b261ecSmrgvoid
5735c4bbdfSmrgFUNC(ScreenPtr pScreen, shadowBufPtr pBuf)
5805b261ecSmrg{
591b5d61b8Smrg    RegionPtr damage = DamageRegion(pBuf->pDamage);
6035c4bbdfSmrg    PixmapPtr pShadow = pBuf->pPixmap;
6135c4bbdfSmrg    int nbox = RegionNumRects(damage);
6235c4bbdfSmrg    BoxPtr pbox = RegionRects(damage);
6335c4bbdfSmrg    FbBits *shaBits;
6435c4bbdfSmrg    Data *shaBase, *shaLine, *sha;
6535c4bbdfSmrg    FbStride shaStride, winStride;
6635c4bbdfSmrg    int shaBpp;
6735c4bbdfSmrg    _X_UNUSED int shaXoff, shaYoff;
6835c4bbdfSmrg    int x, y, w, h;
6935c4bbdfSmrg    Data *winBase, *win, *winLine;
7035c4bbdfSmrg    CARD32 winSize;
7135c4bbdfSmrg
7235c4bbdfSmrg    fbGetDrawable(&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff,
7335c4bbdfSmrg                  shaYoff);
7405b261ecSmrg    shaBase = (Data *) shaBits;
7535c4bbdfSmrg    shaStride = shaStride * sizeof(FbBits) / sizeof(Data);
7605b261ecSmrg
7705b261ecSmrg    winBase = (Data *) (*pBuf->window) (pScreen, 0, 0,
7835c4bbdfSmrg                                        SHADOW_WINDOW_WRITE,
7935c4bbdfSmrg                                        &winSize, pBuf->closure);
8005b261ecSmrg    winStride = (Data *) (*pBuf->window) (pScreen, 1, 0,
8135c4bbdfSmrg                                          SHADOW_WINDOW_WRITE,
8235c4bbdfSmrg                                          &winSize, pBuf->closure) - winBase;
8305b261ecSmrg
8435c4bbdfSmrg    while (nbox--) {
8505b261ecSmrg        x = pbox->x1;
8605b261ecSmrg        y = pbox->y1;
8705b261ecSmrg        w = (pbox->x2 - pbox->x1);
8805b261ecSmrg        h = pbox->y2 - pbox->y1;
8905b261ecSmrg
9035c4bbdfSmrg        shaLine = shaBase + (y * shaStride) + x;
9105b261ecSmrg#ifdef PREFETCH
9235c4bbdfSmrg        __builtin_prefetch(shaLine);
9305b261ecSmrg#endif
9435c4bbdfSmrg        winLine = winBase + WINSTART(x, y);
9505b261ecSmrg
9635c4bbdfSmrg        while (h--) {
9735c4bbdfSmrg            sha = shaLine;
9835c4bbdfSmrg            win = winLine;
9905b261ecSmrg
10035c4bbdfSmrg            while (sha < (shaLine + w - 16)) {
10105b261ecSmrg#ifdef PREFETCH
10235c4bbdfSmrg                __builtin_prefetch(sha + shaStride);
10305b261ecSmrg#endif
10435c4bbdfSmrg                *win = *sha++;
10535c4bbdfSmrg                win += WINSTEPX(winStride);
10635c4bbdfSmrg                *win = *sha++;
10735c4bbdfSmrg                win += WINSTEPX(winStride);
10835c4bbdfSmrg                *win = *sha++;
10935c4bbdfSmrg                win += WINSTEPX(winStride);
11035c4bbdfSmrg                *win = *sha++;
11135c4bbdfSmrg                win += WINSTEPX(winStride);
11235c4bbdfSmrg
11335c4bbdfSmrg                *win = *sha++;
11435c4bbdfSmrg                win += WINSTEPX(winStride);
11535c4bbdfSmrg                *win = *sha++;
11635c4bbdfSmrg                win += WINSTEPX(winStride);
11735c4bbdfSmrg                *win = *sha++;
11835c4bbdfSmrg                win += WINSTEPX(winStride);
11935c4bbdfSmrg                *win = *sha++;
12035c4bbdfSmrg                win += WINSTEPX(winStride);
12135c4bbdfSmrg
12235c4bbdfSmrg                *win = *sha++;
12335c4bbdfSmrg                win += WINSTEPX(winStride);
12435c4bbdfSmrg                *win = *sha++;
12535c4bbdfSmrg                win += WINSTEPX(winStride);
12635c4bbdfSmrg                *win = *sha++;
12735c4bbdfSmrg                win += WINSTEPX(winStride);
12835c4bbdfSmrg                *win = *sha++;
12935c4bbdfSmrg                win += WINSTEPX(winStride);
13035c4bbdfSmrg
13135c4bbdfSmrg                *win = *sha++;
13235c4bbdfSmrg                win += WINSTEPX(winStride);
13335c4bbdfSmrg                *win = *sha++;
13435c4bbdfSmrg                win += WINSTEPX(winStride);
13535c4bbdfSmrg                *win = *sha++;
13635c4bbdfSmrg                win += WINSTEPX(winStride);
13735c4bbdfSmrg                *win = *sha++;
13835c4bbdfSmrg                win += WINSTEPX(winStride);
13905b261ecSmrg            }
14005b261ecSmrg
14135c4bbdfSmrg            while (sha < (shaLine + w)) {
14235c4bbdfSmrg                *win = *sha++;
14335c4bbdfSmrg                win += WINSTEPX(winStride);
14405b261ecSmrg            }
14505b261ecSmrg
14635c4bbdfSmrg            y++;
14735c4bbdfSmrg            shaLine += shaStride;
14835c4bbdfSmrg            winLine += WINSTEPY();
14905b261ecSmrg        }
15005b261ecSmrg        pbox++;
15135c4bbdfSmrg    }                           /*  nbox */
15205b261ecSmrg}
153