xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

fbblt.c (10851B)


      1 /*
      2  * Copyright © 1998 Keith Packard
      3  *
      4  * Permission to use, copy, modify, distribute, and sell this software and its
      5  * documentation for any purpose is hereby granted without fee, provided that
      6  * the above copyright notice appear in all copies and that both that
      7  * copyright notice and this permission notice appear in supporting
      8  * documentation, and that the name of Keith Packard not be used in
      9  * advertising or publicity pertaining to distribution of the software without
     10  * specific, written prior permission.  Keith Packard makes no
     11  * representations about the suitability of this software for any purpose.  It
     12  * is provided "as is" without express or implied warranty.
     13  *
     14  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     16  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     20  * PERFORMANCE OF THIS SOFTWARE.
     21  */
     22 
     23 #ifdef HAVE_DIX_CONFIG_H
     24 #include <dix-config.h>
     25 #endif
     26 
     27 #include <string.h>
     28 #include "fb.h"
     29 
     30 #define InitializeShifts(sx,dx,ls,rs) { \
     31     if (sx != dx) { \
     32 	if (sx > dx) { \
     33 	    ls = sx - dx; \
     34 	    rs = FB_UNIT - ls; \
     35 	} else { \
     36 	    rs = dx - sx; \
     37 	    ls = FB_UNIT - rs; \
     38 	} \
     39     } \
     40 }
     41 
     42 void
     43 fbBlt(FbBits * srcLine,
     44       FbStride srcStride,
     45       int srcX,
     46       FbBits * dstLine,
     47       FbStride dstStride,
     48       int dstX,
     49       int width,
     50       int height, int alu, FbBits pm, int bpp, Bool reverse, Bool upsidedown)
     51 {
     52     FbBits *src, *dst;
     53     int leftShift, rightShift;
     54     FbBits startmask, endmask;
     55     FbBits bits, bits1;
     56     int n, nmiddle;
     57     Bool destInvarient;
     58     int startbyte, endbyte;
     59 
     60     FbDeclareMergeRop();
     61 
     62     if (alu == GXcopy && pm == FB_ALLONES &&
     63         !(srcX & 7) && !(dstX & 7) && !(width & 7))
     64     {
     65         CARD8           *src_byte = (CARD8 *) srcLine + (srcX >> 3);
     66         CARD8           *dst_byte = (CARD8 *) dstLine + (dstX >> 3);
     67         FbStride        src_byte_stride = srcStride << (FB_SHIFT - 3);
     68         FbStride        dst_byte_stride = dstStride << (FB_SHIFT - 3);
     69         int             width_byte = (width >> 3);
     70 
     71         /* Make sure there's no overlap; we can't use memcpy in that
     72          * case as it's not well defined, so fall through to the
     73          * general code
     74          */
     75         if (src_byte + width_byte <= dst_byte ||
     76             dst_byte + width_byte <= src_byte)
     77         {
     78             int i;
     79 
     80             if (!upsidedown)
     81                 for (i = 0; i < height; i++)
     82                     MEMCPY_WRAPPED(dst_byte + i * dst_byte_stride,
     83                                    src_byte + i * src_byte_stride,
     84                                    width_byte);
     85             else
     86                 for (i = height - 1; i >= 0; i--)
     87                     MEMCPY_WRAPPED(dst_byte + i * dst_byte_stride,
     88                                    src_byte + i * src_byte_stride,
     89                                    width_byte);
     90 
     91             return;
     92         }
     93     }
     94 
     95     FbInitializeMergeRop(alu, pm);
     96     destInvarient = FbDestInvarientMergeRop();
     97     if (upsidedown) {
     98         srcLine += (height - 1) * (srcStride);
     99         dstLine += (height - 1) * (dstStride);
    100         srcStride = -srcStride;
    101         dstStride = -dstStride;
    102     }
    103     FbMaskBitsBytes(dstX, width, destInvarient, startmask, startbyte,
    104                     nmiddle, endmask, endbyte);
    105     if (reverse) {
    106         srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1;
    107         dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1;
    108         srcX = (srcX + width - 1) & FB_MASK;
    109         dstX = (dstX + width - 1) & FB_MASK;
    110     }
    111     else {
    112         srcLine += srcX >> FB_SHIFT;
    113         dstLine += dstX >> FB_SHIFT;
    114         srcX &= FB_MASK;
    115         dstX &= FB_MASK;
    116     }
    117     if (srcX == dstX) {
    118         while (height--) {
    119             src = srcLine;
    120             srcLine += srcStride;
    121             dst = dstLine;
    122             dstLine += dstStride;
    123             if (reverse) {
    124                 if (endmask) {
    125                     bits = READ(--src);
    126                     --dst;
    127                     FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
    128                 }
    129                 n = nmiddle;
    130                 if (destInvarient) {
    131                     while (n--)
    132                         WRITE(--dst, FbDoDestInvarientMergeRop(READ(--src)));
    133                 }
    134                 else {
    135                     while (n--) {
    136                         bits = READ(--src);
    137                         --dst;
    138                         WRITE(dst, FbDoMergeRop(bits, READ(dst)));
    139                     }
    140                 }
    141                 if (startmask) {
    142                     bits = READ(--src);
    143                     --dst;
    144                     FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
    145                 }
    146             }
    147             else {
    148                 if (startmask) {
    149                     bits = READ(src++);
    150                     FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
    151                     dst++;
    152                 }
    153                 n = nmiddle;
    154                 if (destInvarient) {
    155 #if 0
    156                     /*
    157                      * This provides some speedup on screen->screen blts
    158                      * over the PCI bus, usually about 10%.  But fb
    159                      * isn't usually used for this operation...
    160                      */
    161                     if (_ca2 + 1 == 0 && _cx2 == 0) {
    162                         FbBits t1, t2, t3, t4;
    163 
    164                         while (n >= 4) {
    165                             t1 = *src++;
    166                             t2 = *src++;
    167                             t3 = *src++;
    168                             t4 = *src++;
    169                             *dst++ = t1;
    170                             *dst++ = t2;
    171                             *dst++ = t3;
    172                             *dst++ = t4;
    173                             n -= 4;
    174                         }
    175                     }
    176 #endif
    177                     while (n--)
    178                         WRITE(dst++, FbDoDestInvarientMergeRop(READ(src++)));
    179                 }
    180                 else {
    181                     while (n--) {
    182                         bits = READ(src++);
    183                         WRITE(dst, FbDoMergeRop(bits, READ(dst)));
    184                         dst++;
    185                     }
    186                 }
    187                 if (endmask) {
    188                     bits = READ(src);
    189                     FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
    190                 }
    191             }
    192         }
    193     }
    194     else {
    195         if (srcX > dstX) {
    196             leftShift = srcX - dstX;
    197             rightShift = FB_UNIT - leftShift;
    198         }
    199         else {
    200             rightShift = dstX - srcX;
    201             leftShift = FB_UNIT - rightShift;
    202         }
    203         while (height--) {
    204             src = srcLine;
    205             srcLine += srcStride;
    206             dst = dstLine;
    207             dstLine += dstStride;
    208 
    209             bits1 = 0;
    210             if (reverse) {
    211                 if (srcX < dstX)
    212                     bits1 = READ(--src);
    213                 if (endmask) {
    214                     bits = FbScrRight(bits1, rightShift);
    215                     if (FbScrRight(endmask, leftShift)) {
    216                         bits1 = READ(--src);
    217                         bits |= FbScrLeft(bits1, leftShift);
    218                     }
    219                     --dst;
    220                     FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
    221                 }
    222                 n = nmiddle;
    223                 if (destInvarient) {
    224                     while (n--) {
    225                         bits = FbScrRight(bits1, rightShift);
    226                         bits1 = READ(--src);
    227                         bits |= FbScrLeft(bits1, leftShift);
    228                         --dst;
    229                         WRITE(dst, FbDoDestInvarientMergeRop(bits));
    230                     }
    231                 }
    232                 else {
    233                     while (n--) {
    234                         bits = FbScrRight(bits1, rightShift);
    235                         bits1 = READ(--src);
    236                         bits |= FbScrLeft(bits1, leftShift);
    237                         --dst;
    238                         WRITE(dst, FbDoMergeRop(bits, READ(dst)));
    239                     }
    240                 }
    241                 if (startmask) {
    242                     bits = FbScrRight(bits1, rightShift);
    243                     if (FbScrRight(startmask, leftShift)) {
    244                         bits1 = READ(--src);
    245                         bits |= FbScrLeft(bits1, leftShift);
    246                     }
    247                     --dst;
    248                     FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
    249                 }
    250             }
    251             else {
    252                 if (srcX > dstX)
    253                     bits1 = READ(src++);
    254                 if (startmask) {
    255                     bits = FbScrLeft(bits1, leftShift);
    256                     if (FbScrLeft(startmask, rightShift)) {
    257                         bits1 = READ(src++);
    258                         bits |= FbScrRight(bits1, rightShift);
    259                     }
    260                     FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
    261                     dst++;
    262                 }
    263                 n = nmiddle;
    264                 if (destInvarient) {
    265                     while (n--) {
    266                         bits = FbScrLeft(bits1, leftShift);
    267                         bits1 = READ(src++);
    268                         bits |= FbScrRight(bits1, rightShift);
    269                         WRITE(dst, FbDoDestInvarientMergeRop(bits));
    270                         dst++;
    271                     }
    272                 }
    273                 else {
    274                     while (n--) {
    275                         bits = FbScrLeft(bits1, leftShift);
    276                         bits1 = READ(src++);
    277                         bits |= FbScrRight(bits1, rightShift);
    278                         WRITE(dst, FbDoMergeRop(bits, READ(dst)));
    279                         dst++;
    280                     }
    281                 }
    282                 if (endmask) {
    283                     bits = FbScrLeft(bits1, leftShift);
    284                     if (FbScrLeft(endmask, rightShift)) {
    285                         bits1 = READ(src);
    286                         bits |= FbScrRight(bits1, rightShift);
    287                     }
    288                     FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
    289                 }
    290             }
    291         }
    292     }
    293 }
    294 
    295 void
    296 fbBltStip(FbStip * src, FbStride srcStride,     /* in FbStip units, not FbBits units */
    297           int srcX, FbStip * dst, FbStride dstStride,   /* in FbStip units, not FbBits units */
    298           int dstX, int width, int height, int alu, FbBits pm, int bpp)
    299 {
    300     fbBlt((FbBits *) src, FbStipStrideToBitsStride(srcStride), srcX,
    301           (FbBits *) dst, FbStipStrideToBitsStride(dstStride), dstX,
    302           width, height, alu, pm, bpp, FALSE, FALSE);
    303 }