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 "SkOpts.h"
     12 #include "SkUtils.h"
     13 
     14 #define UNROLL
     15 
     16 static void S32_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst,
     17                                  const SkPMColor* SK_RESTRICT src,
     18                                  int count, U8CPU alpha) {
     19     SkASSERT(255 == alpha);
     20     memcpy(dst, src, count * 4);
     21 }
     22 
     23 static void S32_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst,
     24                                 const SkPMColor* SK_RESTRICT src,
     25                                 int count, U8CPU alpha) {
     26     SkASSERT(alpha <= 255);
     27     if (count > 0) {
     28         unsigned src_scale = SkAlpha255To256(alpha);
     29         unsigned dst_scale = 256 - src_scale;
     30 
     31 #ifdef UNROLL
     32         if (count & 1) {
     33             *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
     34             dst += 1;
     35             count -= 1;
     36         }
     37 
     38         const SkPMColor* SK_RESTRICT srcEnd = src + count;
     39         while (src != srcEnd) {
     40             *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
     41             dst += 1;
     42             *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale);
     43             dst += 1;
     44         }
     45 #else
     46         do {
     47             *dst = SkAlphaMulQ(*src, src_scale) + SkAlphaMulQ(*dst, dst_scale);
     48             src += 1;
     49             dst += 1;
     50         } while (--count > 0);
     51 #endif
     52     }
     53 }
     54 
     55 static void S32A_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst,
     56                                   const SkPMColor* SK_RESTRICT src,
     57                                   int count, U8CPU alpha) {
     58     SkASSERT(255 == alpha);
     59     if (count > 0) {
     60 #ifdef UNROLL
     61         if (count & 1) {
     62             *dst = SkPMSrcOver(*(src++), *dst);
     63             dst += 1;
     64             count -= 1;
     65         }
     66 
     67         const SkPMColor* SK_RESTRICT srcEnd = src + count;
     68         while (src != srcEnd) {
     69             *dst = SkPMSrcOver(*(src++), *dst);
     70             dst += 1;
     71             *dst = SkPMSrcOver(*(src++), *dst);
     72             dst += 1;
     73         }
     74 #else
     75         do {
     76             *dst = SkPMSrcOver(*src, *dst);
     77             src += 1;
     78             dst += 1;
     79         } while (--count > 0);
     80 #endif
     81     }
     82 }
     83 
     84 static void S32A_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst,
     85                                  const SkPMColor* SK_RESTRICT src,
     86                                  int count, U8CPU alpha) {
     87     SkASSERT(alpha <= 255);
     88     if (count > 0) {
     89 #ifdef UNROLL
     90         if (count & 1) {
     91             *dst = SkBlendARGB32(*(src++), *dst, alpha);
     92             dst += 1;
     93             count -= 1;
     94         }
     95 
     96         const SkPMColor* SK_RESTRICT srcEnd = src + count;
     97         while (src != srcEnd) {
     98             *dst = SkBlendARGB32(*(src++), *dst, alpha);
     99             dst += 1;
    100             *dst = SkBlendARGB32(*(src++), *dst, alpha);
    101             dst += 1;
    102         }
    103 #else
    104         do {
    105             *dst = SkBlendARGB32(*src, *dst, alpha);
    106             src += 1;
    107             dst += 1;
    108         } while (--count > 0);
    109 #endif
    110     }
    111 }
    112 
    113 ///////////////////////////////////////////////////////////////////////////////
    114 
    115 static const SkBlitRow::Proc32 gDefault_Procs32[] = {
    116     S32_Opaque_BlitRow32,
    117     S32_Blend_BlitRow32,
    118     S32A_Opaque_BlitRow32,
    119     S32A_Blend_BlitRow32
    120 };
    121 
    122 SkBlitRow::Proc32 SkBlitRow::Factory32(unsigned flags) {
    123     SkASSERT(flags < SK_ARRAY_COUNT(gDefault_Procs32));
    124     // just so we don't crash
    125     flags &= kFlags32_Mask;
    126 
    127     SkBlitRow::Proc32 proc = PlatformProcs32(flags);
    128     if (nullptr == proc) {
    129         proc = gDefault_Procs32[flags];
    130     }
    131     SkASSERT(proc);
    132     return proc;
    133 }
    134 
    135 void SkBlitRow::Color32(SkPMColor dst[], const SkPMColor src[], int count, SkPMColor color) {
    136     switch (SkGetPackedA32(color)) {
    137         case   0: memmove(dst, src, count * sizeof(SkPMColor)); return;
    138         case 255: sk_memset32(dst, color, count);               return;
    139     }
    140     return SkOpts::blit_row_color32(dst, src, count, color);
    141 }
    142