135c4bbdfSmrg/*
235c4bbdfSmrg *  Copyright © 2013 Geert Uytterhoeven
335c4bbdfSmrg *
435c4bbdfSmrg *  Permission is hereby granted, free of charge, to any person obtaining a
535c4bbdfSmrg *  copy of this software and associated documentation files (the "Software"),
635c4bbdfSmrg *  to deal in the Software without restriction, including without limitation
735c4bbdfSmrg *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
835c4bbdfSmrg *  and/or sell copies of the Software, and to permit persons to whom the
935c4bbdfSmrg *  Software is furnished to do so, subject to the following conditions:
1035c4bbdfSmrg *
1135c4bbdfSmrg *  The above copyright notice and this permission notice (including the next
1235c4bbdfSmrg *  paragraph) shall be included in all copies or substantial portions of the
1335c4bbdfSmrg *  Software.
1435c4bbdfSmrg *
1535c4bbdfSmrg *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1635c4bbdfSmrg *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1735c4bbdfSmrg *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1835c4bbdfSmrg *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1935c4bbdfSmrg *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2035c4bbdfSmrg *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2135c4bbdfSmrg *  DEALINGS IN THE SOFTWARE.
2235c4bbdfSmrg *
2335c4bbdfSmrg *  Based on shpacked.c, which is Copyright © 2000 Keith Packard
2435c4bbdfSmrg */
2535c4bbdfSmrg
2635c4bbdfSmrg#ifdef HAVE_DIX_CONFIG_H
2735c4bbdfSmrg#include <dix-config.h>
2835c4bbdfSmrg#endif
2935c4bbdfSmrg
3035c4bbdfSmrg#include <stdlib.h>
3135c4bbdfSmrg
3235c4bbdfSmrg#include    <X11/X.h>
3335c4bbdfSmrg#include    "scrnintstr.h"
3435c4bbdfSmrg#include    "windowstr.h"
3535c4bbdfSmrg#include    <X11/fonts/font.h>
3635c4bbdfSmrg#include    "dixfontstr.h"
3735c4bbdfSmrg#include    <X11/fonts/fontstruct.h>
3835c4bbdfSmrg#include    "mi.h"
3935c4bbdfSmrg#include    "regionstr.h"
4035c4bbdfSmrg#include    "globals.h"
4135c4bbdfSmrg#include    "gcstruct.h"
4235c4bbdfSmrg#include    "shadow.h"
4335c4bbdfSmrg#include    "fb.h"
4435c4bbdfSmrg#include    "c2p_core.h"
4535c4bbdfSmrg
4635c4bbdfSmrg
4735c4bbdfSmrg    /*
4835c4bbdfSmrg     *  Perform a full C2P step on 32 4-bit pixels, stored in 4 32-bit words
4935c4bbdfSmrg     *  containing
5035c4bbdfSmrg     *    - 32 4-bit chunky pixels on input
5135c4bbdfSmrg     *    - permutated planar data (1 plane per 32-bit word) on output
5235c4bbdfSmrg     */
5335c4bbdfSmrg
5435c4bbdfSmrgstatic void c2p_32x4(CARD32 d[4])
5535c4bbdfSmrg{
5635c4bbdfSmrg    transp4(d, 16, 2);
5735c4bbdfSmrg    transp4(d, 8, 1);
5835c4bbdfSmrg    transp4(d, 4, 2);
5935c4bbdfSmrg    transp4(d, 2, 1);
6035c4bbdfSmrg    transp4(d, 1, 2);
6135c4bbdfSmrg}
6235c4bbdfSmrg
6335c4bbdfSmrg
6435c4bbdfSmrg    /*
6535c4bbdfSmrg     *  Store a full block of permutated planar data after c2p conversion
6635c4bbdfSmrg     */
6735c4bbdfSmrg
6835c4bbdfSmrgstatic inline void store_afb4(void *dst, unsigned int stride,
6935c4bbdfSmrg                              const CARD32 d[4])
7035c4bbdfSmrg{
7135c4bbdfSmrg    CARD8 *p = dst;
7235c4bbdfSmrg
7335c4bbdfSmrg    *(CARD32 *)p = d[3]; p += stride;
7435c4bbdfSmrg    *(CARD32 *)p = d[1]; p += stride;
7535c4bbdfSmrg    *(CARD32 *)p = d[2]; p += stride;
7635c4bbdfSmrg    *(CARD32 *)p = d[0]; p += stride;
7735c4bbdfSmrg}
7835c4bbdfSmrg
7935c4bbdfSmrg
8035c4bbdfSmrgvoid
8135c4bbdfSmrgshadowUpdateAfb4(ScreenPtr pScreen, shadowBufPtr pBuf)
8235c4bbdfSmrg{
831b5d61b8Smrg    RegionPtr damage = DamageRegion(pBuf->pDamage);
8435c4bbdfSmrg    PixmapPtr pShadow = pBuf->pPixmap;
8535c4bbdfSmrg    int nbox = RegionNumRects(damage);
8635c4bbdfSmrg    BoxPtr pbox = RegionRects(damage);
8735c4bbdfSmrg    FbBits *shaBase;
8835c4bbdfSmrg    CARD32 *shaLine, *sha;
8935c4bbdfSmrg    FbStride shaStride;
9035c4bbdfSmrg    int scrLine;
9135c4bbdfSmrg    _X_UNUSED int shaBpp, shaXoff, shaYoff;
9235c4bbdfSmrg    int x, y, w, h;
9335c4bbdfSmrg    int i, n;
9435c4bbdfSmrg    CARD32 *win;
9535c4bbdfSmrg    CARD32 off, winStride;
9635c4bbdfSmrg    union {
9735c4bbdfSmrg        CARD8 bytes[16];
9835c4bbdfSmrg        CARD32 words[4];
9935c4bbdfSmrg    } d;
10035c4bbdfSmrg
10135c4bbdfSmrg    fbGetDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff,
10235c4bbdfSmrg                  shaYoff);
10335c4bbdfSmrg    if (sizeof(FbBits) != sizeof(CARD32))
10435c4bbdfSmrg        shaStride = shaStride * sizeof(FbBits) / sizeof(CARD32);
10535c4bbdfSmrg
10635c4bbdfSmrg    while (nbox--) {
10735c4bbdfSmrg        x = pbox->x1;
10835c4bbdfSmrg        y = pbox->y1;
10935c4bbdfSmrg        w = pbox->x2 - pbox->x1;
11035c4bbdfSmrg        h = pbox->y2 - pbox->y1;
11135c4bbdfSmrg
11235c4bbdfSmrg        scrLine = (x & -32) / 2;
11335c4bbdfSmrg        shaLine = (CARD32 *)shaBase + y * shaStride + scrLine / sizeof(CARD32);
11435c4bbdfSmrg
11535c4bbdfSmrg        off = scrLine / 4;              /* byte offset in bitplane scanline */
11635c4bbdfSmrg        n = ((x & 31) + w + 31) / 32;   /* number of c2p units in scanline */
11735c4bbdfSmrg
11835c4bbdfSmrg        while (h--) {
11935c4bbdfSmrg            sha = shaLine;
12035c4bbdfSmrg            win = (CARD32 *) (*pBuf->window) (pScreen,
12135c4bbdfSmrg                                             y,
12235c4bbdfSmrg                                             off,
12335c4bbdfSmrg                                             SHADOW_WINDOW_WRITE,
12435c4bbdfSmrg                                             &winStride,
12535c4bbdfSmrg                                             pBuf->closure);
12635c4bbdfSmrg            if (!win)
12735c4bbdfSmrg                return;
12835c4bbdfSmrg            for (i = 0; i < n; i++) {
12935c4bbdfSmrg                memcpy(d.bytes, sha, sizeof(d.bytes));
13035c4bbdfSmrg                c2p_32x4(d.words);
13135c4bbdfSmrg                store_afb4(win++, winStride, d.words);
13235c4bbdfSmrg                sha += sizeof(d.bytes) / sizeof(*sha);
13335c4bbdfSmrg            }
13435c4bbdfSmrg            shaLine += shaStride;
13535c4bbdfSmrg            y++;
13635c4bbdfSmrg        }
13735c4bbdfSmrg        pbox++;
13835c4bbdfSmrg    }
13935c4bbdfSmrg}
14001260a01Sjandberg
14101260a01Sjandberg    /*
14201260a01Sjandberg     * Like above, except input is 8-bit chunky pixels (upper 4 bits zero)
14301260a01Sjandberg     */
14401260a01Sjandbergvoid
14501260a01SjandbergshadowUpdateAfb4x8(ScreenPtr pScreen, shadowBufPtr pBuf)
14601260a01Sjandberg{
14701260a01Sjandberg    RegionPtr damage = DamageRegion(pBuf->pDamage);
14801260a01Sjandberg    PixmapPtr pShadow = pBuf->pPixmap;
14901260a01Sjandberg    int nbox = RegionNumRects(damage);
15001260a01Sjandberg    BoxPtr pbox = RegionRects(damage);
15101260a01Sjandberg    FbBits *shaBase;
15201260a01Sjandberg    CARD32 *shaLine, *sha;
15301260a01Sjandberg    FbStride shaStride;
15401260a01Sjandberg    int scrLine;
15501260a01Sjandberg    _X_UNUSED int shaBpp, shaXoff, shaYoff;
15601260a01Sjandberg    int x, y, w, h;
15701260a01Sjandberg    int i, n;
15801260a01Sjandberg    CARD32 *win;
15901260a01Sjandberg    CARD32 off, winStride;
16001260a01Sjandberg    CARD32 dwords[4];
16101260a01Sjandberg
16201260a01Sjandberg    fbGetDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff,
16301260a01Sjandberg                  shaYoff);
16401260a01Sjandberg    if (sizeof(FbBits) != sizeof(CARD32))
16501260a01Sjandberg        shaStride = shaStride * sizeof(FbBits) / sizeof(CARD32);
16601260a01Sjandberg
16701260a01Sjandberg    while (nbox--) {
16801260a01Sjandberg        x = pbox->x1;
16901260a01Sjandberg        y = pbox->y1;
17001260a01Sjandberg        w = pbox->x2 - pbox->x1;
17101260a01Sjandberg        h = pbox->y2 - pbox->y1;
17201260a01Sjandberg
17301260a01Sjandberg        scrLine = x & -32;
17401260a01Sjandberg        shaLine = (CARD32 *)shaBase + y * shaStride + scrLine / sizeof(CARD32);
17501260a01Sjandberg
17601260a01Sjandberg        off = scrLine / 8;              /* byte offset in bitplane scanline */
17701260a01Sjandberg        n = ((x & 31) + w + 31) / 32;   /* number of c2p units in scanline */
17801260a01Sjandberg
17901260a01Sjandberg        while (h--) {
18001260a01Sjandberg            sha = shaLine;
18101260a01Sjandberg            win = (CARD32 *) (*pBuf->window) (pScreen,
18201260a01Sjandberg                                             y,
18301260a01Sjandberg                                             off,
18401260a01Sjandberg                                             SHADOW_WINDOW_WRITE,
18501260a01Sjandberg                                             &winStride,
18601260a01Sjandberg                                             pBuf->closure);
18701260a01Sjandberg            if (!win)
18801260a01Sjandberg                return;
18901260a01Sjandberg            for (i = 0; i < n; i++) {
19001260a01Sjandberg                dwords[0] = (sha[0] << 4) | sha[1];
19101260a01Sjandberg                dwords[2] = (sha[2] << 4) | sha[3];
19201260a01Sjandberg                dwords[1] = (sha[4] << 4) | sha[5];
19301260a01Sjandberg                dwords[3] = (sha[6] << 4) | sha[7];
19401260a01Sjandberg                transp4(dwords, 16, 1);
19501260a01Sjandberg                transp4(dwords, 8, 2);
19601260a01Sjandberg                transp4(dwords, 2, 1);
19701260a01Sjandberg                transp4(dwords, 1, 2);
19801260a01Sjandberg                store_afb4(win++, winStride, dwords);
19901260a01Sjandberg                sha += 8;
20001260a01Sjandberg            }
20101260a01Sjandberg            shaLine += shaStride;
20201260a01Sjandberg            y++;
20301260a01Sjandberg        }
20401260a01Sjandberg        pbox++;
20501260a01Sjandberg    }
20601260a01Sjandberg}
207