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