Home | History | Annotate | Download | only in core
      1 #include "SkBlitRow.h"
      2 #include "SkColorPriv.h"
      3 #include "SkDither.h"
      4 
      5 ///////////////////////////////////////////////////////////////////////////////
      6 
      7 static void S32_D4444_Opaque(uint16_t* SK_RESTRICT dst,
      8                              const SkPMColor* SK_RESTRICT src, int count,
      9                              U8CPU alpha, int /*x*/, int /*y*/) {
     10     SkASSERT(255 == alpha);
     11 
     12     if (count > 0) {
     13         do {
     14             SkPMColor c = *src++;
     15             SkPMColorAssert(c);
     16             SkASSERT(SkGetPackedA32(c) == 255);
     17             *dst++ = SkPixel32ToPixel4444(c);
     18         } while (--count != 0);
     19     }
     20 }
     21 
     22 static void S32_D4444_Blend(uint16_t* SK_RESTRICT dst,
     23                             const SkPMColor* SK_RESTRICT src, int count,
     24                             U8CPU alpha, int /*x*/, int /*y*/) {
     25     SkASSERT(255 > alpha);
     26 
     27     if (count > 0) {
     28         unsigned scale16 = SkAlpha255To256(alpha) >> 4;
     29         do {
     30             SkPMColor c = *src++;
     31             SkPMColorAssert(c);
     32             SkASSERT(SkGetPackedA32(c) == 255);
     33 
     34             uint32_t src_expand = SkExpand32_4444(c);
     35             uint32_t dst_expand = SkExpand_4444(*dst);
     36             dst_expand += (src_expand - dst_expand) * scale16 >> 4;
     37             *dst++ = SkCompact_4444(dst_expand);
     38         } while (--count != 0);
     39     }
     40 }
     41 
     42 static void S32A_D4444_Opaque(uint16_t* SK_RESTRICT dst,
     43                               const SkPMColor* SK_RESTRICT src, int count,
     44                               U8CPU alpha, int /*x*/, int /*y*/) {
     45     SkASSERT(255 == alpha);
     46 
     47     if (count > 0) {
     48         do {
     49             SkPMColor c = *src++;
     50             SkPMColorAssert(c);
     51 //            if (__builtin_expect(c!=0, 1))
     52             if (c)
     53             {
     54                 unsigned scale16 = SkAlpha255To256(255 - SkGetPackedA32(c)) >> 4;
     55                 uint32_t src_expand = SkExpand_8888(c);
     56                 uint32_t dst_expand = SkExpand_4444(*dst) * scale16;
     57                 *dst = SkCompact_4444((src_expand + dst_expand) >> 4);
     58             }
     59             dst += 1;
     60         } while (--count != 0);
     61     }
     62 }
     63 
     64 static void S32A_D4444_Blend(uint16_t* SK_RESTRICT dst,
     65                              const SkPMColor* SK_RESTRICT src, int count,
     66                              U8CPU alpha, int /*x*/, int /*y*/) {
     67     SkASSERT(255 > alpha);
     68 
     69     if (count > 0) {
     70         int src_scale = SkAlpha255To256(alpha) >> 4;
     71         do {
     72             SkPMColor sc = *src++;
     73             SkPMColorAssert(sc);
     74 
     75             if (sc) {
     76                 unsigned dst_scale = 16 - (SkGetPackedA32(sc) * src_scale >> 8);
     77                 uint32_t src_expand = SkExpand32_4444(sc) * src_scale;
     78                 uint32_t dst_expand = SkExpand_4444(*dst) * dst_scale;
     79                 *dst = SkCompact_4444((src_expand + dst_expand) >> 4);
     80             }
     81             dst += 1;
     82         } while (--count != 0);
     83     }
     84 }
     85 
     86 /////////////////////////////////////////////////////////////////////////////
     87 
     88 static void S32_D4444_Opaque_Dither(uint16_t* SK_RESTRICT dst,
     89                                     const SkPMColor* SK_RESTRICT src,
     90                                     int count, U8CPU alpha, int x, int y) {
     91     SkASSERT(255 == alpha);
     92 
     93     if (count > 0) {
     94         DITHER_4444_SCAN(y);
     95         do {
     96             SkPMColor c = *src++;
     97             SkPMColorAssert(c);
     98             SkASSERT(SkGetPackedA32(c) == 255);
     99 
    100             unsigned dither = DITHER_VALUE(x);
    101             *dst++ = SkDitherARGB32To4444(c, dither);
    102             DITHER_INC_X(x);
    103         } while (--count != 0);
    104     }
    105 }
    106 
    107 static void S32_D4444_Blend_Dither(uint16_t* SK_RESTRICT dst,
    108                                    const SkPMColor* SK_RESTRICT src,
    109                                    int count, U8CPU alpha, int x, int y) {
    110     SkASSERT(255 > alpha);
    111 
    112     if (count > 0) {
    113         int scale16 = SkAlpha255To256(alpha) >> 4;
    114         DITHER_4444_SCAN(y);
    115         do {
    116             SkPMColor c = *src++;
    117             SkPMColorAssert(c);
    118             SkASSERT(SkGetPackedA32(c) == 255);
    119 
    120             uint32_t src_expand = SkExpand32_4444(c) * scale16;
    121             uint32_t dst_expand = SkExpand_4444(*dst) * (16 - scale16);
    122 
    123             c = SkCompact_8888(src_expand + dst_expand); // convert back to SkPMColor
    124             *dst++ = SkDitherARGB32To4444(c, DITHER_VALUE(x));
    125             DITHER_INC_X(x);
    126         } while (--count != 0);
    127     }
    128 }
    129 
    130 static void S32A_D4444_Opaque_Dither(uint16_t* SK_RESTRICT dst,
    131                                      const SkPMColor* SK_RESTRICT src,
    132                                      int count, U8CPU alpha, int x, int y) {
    133     SkASSERT(255 == alpha);
    134 
    135     if (count > 0) {
    136         DITHER_4444_SCAN(y);
    137         do {
    138             SkPMColor c = *src++;
    139             SkPMColorAssert(c);
    140             if (c) {
    141                 unsigned a = SkGetPackedA32(c);
    142                 int d = SkAlphaMul(DITHER_VALUE(x), SkAlpha255To256(a));
    143 
    144                 unsigned scale16 = SkAlpha255To256(255 - a) >> 4;
    145                 uint32_t src_expand = SkExpand_8888(c);
    146                 uint32_t dst_expand = SkExpand_4444(*dst) * scale16;
    147                 // convert back to SkPMColor
    148                 c = SkCompact_8888(src_expand + dst_expand);
    149                 *dst = SkDitherARGB32To4444(c, d);
    150             }
    151             dst += 1;
    152             DITHER_INC_X(x);
    153         } while (--count != 0);
    154     }
    155 }
    156 
    157 // need DitherExpand888To4444(expand, dither)
    158 
    159 static void S32A_D4444_Blend_Dither(uint16_t* SK_RESTRICT dst,
    160                                     const SkPMColor* SK_RESTRICT src,
    161                                     int count, U8CPU alpha, int x, int y) {
    162     SkASSERT(255 > alpha);
    163 
    164     if (count > 0) {
    165         int src_scale = SkAlpha255To256(alpha) >> 4;
    166         DITHER_4444_SCAN(y);
    167         do {
    168             SkPMColor c = *src++;
    169             SkPMColorAssert(c);
    170             if (c) {
    171                 unsigned a = SkAlpha255To256(SkGetPackedA32(c));
    172                 int d = SkAlphaMul(DITHER_VALUE(x), a);
    173 
    174                 unsigned dst_scale = 16 - SkAlphaMul(src_scale, a);
    175                 uint32_t src_expand = SkExpand32_4444(c) * src_scale;
    176                 uint32_t dst_expand = SkExpand_4444(*dst) * dst_scale;
    177                 // convert back to SkPMColor
    178                 c = SkCompact_8888(src_expand + dst_expand);
    179                 *dst = SkDitherARGB32To4444(c, d);
    180             }
    181             dst += 1;
    182             DITHER_INC_X(x);
    183         } while (--count != 0);
    184     }
    185 }
    186 
    187 ///////////////////////////////////////////////////////////////////////////////
    188 ///////////////////////////////////////////////////////////////////////////////
    189 
    190 static const SkBlitRow::Proc gProcs4444[] = {
    191     // no dither
    192     S32_D4444_Opaque,
    193     S32_D4444_Blend,
    194 
    195     S32A_D4444_Opaque,
    196     S32A_D4444_Blend,
    197 
    198     // dither
    199     S32_D4444_Opaque_Dither,
    200     S32_D4444_Blend_Dither,
    201 
    202     S32A_D4444_Opaque_Dither,
    203     S32A_D4444_Blend_Dither
    204 };
    205 
    206 SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags);
    207 SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags)
    208 {
    209     SkASSERT(flags < SK_ARRAY_COUNT(gProcs4444));
    210 
    211     return gProcs4444[flags];
    212 }
    213 
    214 
    215