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 15static 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 22static 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 56static 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 97static 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 128static const SkBlitRow::Proc32 gDefault_Procs32[] = { 129 S32_Opaque_BlitRow32, 130 S32_Blend_BlitRow32, 131 S32A_Opaque_BlitRow32, 132 S32A_Blend_BlitRow32 133}; 134 135SkBlitRow::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 148SkBlitRow::Proc32 SkBlitRow::ColorProcFactory() { 149 SkBlitRow::ColorProc proc = PlatformColorProc(); 150 if (NULL == proc) { 151 proc = Color32; 152 } 153 SkASSERT(proc); 154 return proc; 155} 156 157void 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