Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2011 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkBlitRow.h"
      9 #include "SkBlitMask.h"
     10 #include "SkColorPriv.h"
     11 #include "SkUtils.h"
     12 
     13 #define UNROLL
     14 
     15 static void S32_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst,
     16                                  const SkPMColor* SK_RESTRICT src,
     17                                  int count, U8CPU alpha) {
     18     SkASSERT(255 == alpha);
     19     memcpy(dst, src, count * sizeof(SkPMColor));
     20 }
     21 
     22 static void S32_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst,
     23                                 const SkPMColor* SK_RESTRICT src,
     24                                 int count, U8CPU alpha) {
     25     SkASSERT(alpha <= 255);
     26     if (count > 0) {
     27         unsigned src_scale = SkAlpha255To256(alpha);
     28         unsigned dst_scale = 256 - src_scale;
     29 
     30 #ifdef UNROLL
     31         if (count & 1) {
     32             *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
     33             dst += 1;
     34             count -= 1;
     35         }
     36 
     37         const SkPMColor* SK_RESTRICT srcEnd = src + count;
     38         while (src != srcEnd) {
     39             *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
     40             dst += 1;
     41             *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
     42             dst += 1;
     43         }
     44 #else
     45         do {
     46             *dst = SkAlphaMulQ(*src, src_scale) + SkAlphaMulQ(*dst, dst_scale);
     47             src += 1;
     48             dst += 1;
     49         } while (--count > 0);
     50 #endif
     51     }
     52 }
     53 
     54 //#define TEST_SRC_ALPHA
     55 
     56 static void S32A_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst,
     57                                   const SkPMColor* SK_RESTRICT src,
     58                                   int count, U8CPU alpha) {
     59     SkASSERT(255 == alpha);
     60     if (count > 0) {
     61 #ifdef UNROLL
     62         if (count & 1) {
     63             *dst = SkPMSrcOver(*(src++), *dst);
     64             dst += 1;
     65             count -= 1;
     66         }
     67 
     68         const SkPMColor* SK_RESTRICT srcEnd = src + count;
     69         while (src != srcEnd) {
     70             *dst = SkPMSrcOver(*(src++), *dst);
     71             dst += 1;
     72             *dst = SkPMSrcOver(*(src++), *dst);
     73             dst += 1;
     74         }
     75 #else
     76         do {
     77 #ifdef TEST_SRC_ALPHA
     78             SkPMColor sc = *src;
     79             if (sc) {
     80                 unsigned srcA = SkGetPackedA32(sc);
     81                 SkPMColor result = sc;
     82                 if (srcA != 255) {
     83                     result = SkPMSrcOver(sc, *dst);
     84                 }
     85                 *dst = result;
     86             }
     87 #else
     88             *dst = SkPMSrcOver(*src, *dst);
     89 #endif
     90             src += 1;
     91             dst += 1;
     92         } while (--count > 0);
     93 #endif
     94     }
     95 }
     96 
     97 static void S32A_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst,
     98                                  const SkPMColor* SK_RESTRICT src,
     99                                  int count, U8CPU alpha) {
    100     SkASSERT(alpha <= 255);
    101     if (count > 0) {
    102 #ifdef UNROLL
    103         if (count & 1) {
    104             *dst = SkBlendARGB32(*(src++), *dst, alpha);
    105             dst += 1;
    106             count -= 1;
    107         }
    108 
    109         const SkPMColor* SK_RESTRICT srcEnd = src + count;
    110         while (src != srcEnd) {
    111             *dst = SkBlendARGB32(*(src++), *dst, alpha);
    112             dst += 1;
    113             *dst = SkBlendARGB32(*(src++), *dst, alpha);
    114             dst += 1;
    115         }
    116 #else
    117         do {
    118             *dst = SkBlendARGB32(*src, *dst, alpha);
    119             src += 1;
    120             dst += 1;
    121         } while (--count > 0);
    122 #endif
    123     }
    124 }
    125 
    126 ///////////////////////////////////////////////////////////////////////////////
    127 
    128 static const SkBlitRow::Proc32 gDefault_Procs32[] = {
    129     S32_Opaque_BlitRow32,
    130     S32_Blend_BlitRow32,
    131     S32A_Opaque_BlitRow32,
    132     S32A_Blend_BlitRow32
    133 };
    134 
    135 SkBlitRow::Proc32 SkBlitRow::Factory32(unsigned flags) {
    136     SkASSERT(flags < SK_ARRAY_COUNT(gDefault_Procs32));
    137     // just so we don't crash
    138     flags &= kFlags32_Mask;
    139 
    140     SkBlitRow::Proc32 proc = PlatformProcs32(flags);
    141     if (NULL == proc) {
    142         proc = gDefault_Procs32[flags];
    143     }
    144     SkASSERT(proc);
    145     return proc;
    146 }
    147 
    148 SkBlitRow::Proc32 SkBlitRow::ColorProcFactory() {
    149     SkBlitRow::ColorProc proc = PlatformColorProc();
    150     if (NULL == proc) {
    151         proc = Color32;
    152     }
    153     SkASSERT(proc);
    154     return proc;
    155 }
    156 
    157 void SkBlitRow::Color32(SkPMColor* SK_RESTRICT dst,
    158                         const SkPMColor* SK_RESTRICT src,
    159                         int count, SkPMColor color) {
    160     if (count > 0) {
    161         if (0 == color) {
    162             if (src != dst) {
    163                 memcpy(dst, src, count * sizeof(SkPMColor));
    164             }
    165             return;
    166         }
    167         unsigned colorA = SkGetPackedA32(color);
    168         if (255 == colorA) {
    169             sk_memset32(dst, color, count);
    170         } else {
    171             unsigned scale = 256 - SkAlpha255To256(colorA);
    172             do {
    173                 *dst = color + SkAlphaMulQ(*src, scale);
    174                 src += 1;
    175                 dst += 1;
    176             } while (--count);
    177         }
    178     }
    179 }
    180 
    181