SkBlitRow_D32.cpp revision 981d4798007b91e2e19c13b171583927a56df63b
1#include "SkBlitRow.h" 2#include "SkColorPriv.h" 3#include "SkUtils.h" 4 5#define UNROLL 6 7static void S32_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst, 8 const SkPMColor* SK_RESTRICT src, 9 int count, U8CPU alpha) { 10 SkASSERT(255 == alpha); 11 memcpy(dst, src, count * sizeof(SkPMColor)); 12} 13 14static void S32_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst, 15 const SkPMColor* SK_RESTRICT src, 16 int count, U8CPU alpha) { 17 SkASSERT(alpha <= 255); 18 if (count > 0) { 19 unsigned src_scale = SkAlpha255To256(alpha); 20 unsigned dst_scale = 256 - src_scale; 21 22#ifdef UNROLL 23 if (count & 1) { 24 *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale); 25 dst += 1; 26 count -= 1; 27 } 28 29 const SkPMColor* SK_RESTRICT srcEnd = src + count; 30 while (src != srcEnd) { 31 *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale); 32 dst += 1; 33 *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale); 34 dst += 1; 35 } 36#else 37 do { 38 *dst = SkAlphaMulQ(*src, src_scale) + SkAlphaMulQ(*dst, dst_scale); 39 src += 1; 40 dst += 1; 41 } while (--count > 0); 42#endif 43 } 44} 45 46//#define TEST_SRC_ALPHA 47 48static void S32A_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst, 49 const SkPMColor* SK_RESTRICT src, 50 int count, U8CPU alpha) { 51 SkASSERT(255 == alpha); 52 if (count > 0) { 53#ifdef UNROLL 54 if (count & 1) { 55 *dst = SkPMSrcOver(*(src++), *dst); 56 dst += 1; 57 count -= 1; 58 } 59 60 const SkPMColor* SK_RESTRICT srcEnd = src + count; 61 while (src != srcEnd) { 62 *dst = SkPMSrcOver(*(src++), *dst); 63 dst += 1; 64 *dst = SkPMSrcOver(*(src++), *dst); 65 dst += 1; 66 } 67#else 68 do { 69#ifdef TEST_SRC_ALPHA 70 SkPMColor sc = *src; 71 if (sc) { 72 unsigned srcA = SkGetPackedA32(sc); 73 SkPMColor result = sc; 74 if (srcA != 255) { 75 result = SkPMSrcOver(sc, *dst); 76 } 77 *dst = result; 78 } 79#else 80 *dst = SkPMSrcOver(*src, *dst); 81#endif 82 src += 1; 83 dst += 1; 84 } while (--count > 0); 85#endif 86 } 87} 88 89static void S32A_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst, 90 const SkPMColor* SK_RESTRICT src, 91 int count, U8CPU alpha) { 92 SkASSERT(alpha <= 255); 93 if (count > 0) { 94#ifdef UNROLL 95 if (count & 1) { 96 *dst = SkBlendARGB32(*(src++), *dst, alpha); 97 dst += 1; 98 count -= 1; 99 } 100 101 const SkPMColor* SK_RESTRICT srcEnd = src + count; 102 while (src != srcEnd) { 103 *dst = SkBlendARGB32(*(src++), *dst, alpha); 104 dst += 1; 105 *dst = SkBlendARGB32(*(src++), *dst, alpha); 106 dst += 1; 107 } 108#else 109 do { 110 *dst = SkBlendARGB32(*src, *dst, alpha); 111 src += 1; 112 dst += 1; 113 } while (--count > 0); 114#endif 115 } 116} 117 118/////////////////////////////////////////////////////////////////////////////// 119 120static const SkBlitRow::Proc32 gDefault_Procs32[] = { 121 S32_Opaque_BlitRow32, 122 S32_Blend_BlitRow32, 123 S32A_Opaque_BlitRow32, 124 S32A_Blend_BlitRow32 125}; 126 127SkBlitRow::Proc32 SkBlitRow::Factory32(unsigned flags) { 128 SkASSERT(flags < SK_ARRAY_COUNT(gDefault_Procs32)); 129 // just so we don't crash 130 flags &= kFlags32_Mask; 131 132 SkBlitRow::Proc32 proc = PlatformProcs32(flags); 133 if (NULL == proc) { 134 proc = gDefault_Procs32[flags]; 135 } 136 SkASSERT(proc); 137 return proc; 138} 139 140SkBlitRow::Proc32 SkBlitRow::ColorProcFactory() { 141 SkBlitRow::ColorProc proc = PlatformColorProc(); 142 if (NULL == proc) { 143 proc = Color32; 144 } 145 SkASSERT(proc); 146 return proc; 147} 148 149void SkBlitRow::Color32(SkPMColor dst[], const SkPMColor src[], 150 int count, SkPMColor color) { 151 if (count > 0) { 152 if (0 == color) { 153 if (src != dst) { 154 memcpy(dst, src, count * sizeof(SkPMColor)); 155 } 156 } 157 unsigned colorA = SkGetPackedA32(color); 158 if (255 == colorA) { 159 sk_memset32(dst, color, count); 160 } else { 161 unsigned scale = 256 - SkAlpha255To256(colorA); 162 do { 163 *dst = color + SkAlphaMulQ(*src, scale); 164 src += 1; 165 dst += 1; 166 } while (--count); 167 } 168 } 169} 170 171/////////////////////////////////////////////////////////////////////////////// 172 173static void SkARGB32_BlitMask_portable(void* dst, size_t dstRB, 174 SkBitmap::Config dstConfig, 175 const uint8_t* mask, 176 size_t maskRB, SkColor color, 177 int width, int height) { 178 size_t dstOffset = dstRB - (width << 2); 179 size_t maskOffset = maskRB - width; 180 SkPMColor *device = (SkPMColor *)dst; 181 do { 182 int w = width; 183 do { 184 unsigned aa = *mask++; 185 *device = SkBlendARGB32(color, *device, aa); 186 device += 1; 187 } while (--w != 0); 188 device = (uint32_t*)((char*)device + dstOffset); 189 mask += maskOffset; 190 } while (--height != 0); 191} 192 193SkBlitMask::Proc SkBlitMask::Factory(SkBitmap::Config config, SkColor color) { 194 SkBlitMask::Proc proc = PlatformProcs(config, color); 195 if (NULL == proc) { 196 switch (config) { 197 case SkBitmap::kARGB_8888_Config: 198 if ( SK_ColorBLACK != color && 0xFF != SkColorGetA(color) ) { 199 //TODO: blitmask for black; 200 //TODO: blitmask for opaque; 201 proc = SkARGB32_BlitMask_portable; 202 } 203 break; 204 default: 205 break; 206 } 207 } 208 return proc; 209} 210 211