1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/core/SkBlitRow_D32.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,249 @@ 1.4 +/* 1.5 + * Copyright 2011 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#include "SkBlitRow.h" 1.12 +#include "SkBlitMask.h" 1.13 +#include "SkColorPriv.h" 1.14 +#include "SkUtils.h" 1.15 + 1.16 +#define UNROLL 1.17 + 1.18 +SkBlitRow::ColorRectProc PlatformColorRectProcFactory(); 1.19 + 1.20 +static void S32_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst, 1.21 + const SkPMColor* SK_RESTRICT src, 1.22 + int count, U8CPU alpha) { 1.23 + SkASSERT(255 == alpha); 1.24 + memcpy(dst, src, count * sizeof(SkPMColor)); 1.25 +} 1.26 + 1.27 +static void S32_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst, 1.28 + const SkPMColor* SK_RESTRICT src, 1.29 + int count, U8CPU alpha) { 1.30 + SkASSERT(alpha <= 255); 1.31 + if (count > 0) { 1.32 + unsigned src_scale = SkAlpha255To256(alpha); 1.33 + unsigned dst_scale = 256 - src_scale; 1.34 + 1.35 +#ifdef UNROLL 1.36 + if (count & 1) { 1.37 + *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale); 1.38 + dst += 1; 1.39 + count -= 1; 1.40 + } 1.41 + 1.42 + const SkPMColor* SK_RESTRICT srcEnd = src + count; 1.43 + while (src != srcEnd) { 1.44 + *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale); 1.45 + dst += 1; 1.46 + *dst = SkAlphaMulQ(*(src++), src_scale) + SkAlphaMulQ(*dst, dst_scale); 1.47 + dst += 1; 1.48 + } 1.49 +#else 1.50 + do { 1.51 + *dst = SkAlphaMulQ(*src, src_scale) + SkAlphaMulQ(*dst, dst_scale); 1.52 + src += 1; 1.53 + dst += 1; 1.54 + } while (--count > 0); 1.55 +#endif 1.56 + } 1.57 +} 1.58 + 1.59 +static void S32A_Opaque_BlitRow32(SkPMColor* SK_RESTRICT dst, 1.60 + const SkPMColor* SK_RESTRICT src, 1.61 + int count, U8CPU alpha) { 1.62 + SkASSERT(255 == alpha); 1.63 + if (count > 0) { 1.64 +#ifdef UNROLL 1.65 + if (count & 1) { 1.66 + *dst = SkPMSrcOver(*(src++), *dst); 1.67 + dst += 1; 1.68 + count -= 1; 1.69 + } 1.70 + 1.71 + const SkPMColor* SK_RESTRICT srcEnd = src + count; 1.72 + while (src != srcEnd) { 1.73 + *dst = SkPMSrcOver(*(src++), *dst); 1.74 + dst += 1; 1.75 + *dst = SkPMSrcOver(*(src++), *dst); 1.76 + dst += 1; 1.77 + } 1.78 +#else 1.79 + do { 1.80 + *dst = SkPMSrcOver(*src, *dst); 1.81 + src += 1; 1.82 + dst += 1; 1.83 + } while (--count > 0); 1.84 +#endif 1.85 + } 1.86 +} 1.87 + 1.88 +static void S32A_Blend_BlitRow32(SkPMColor* SK_RESTRICT dst, 1.89 + const SkPMColor* SK_RESTRICT src, 1.90 + int count, U8CPU alpha) { 1.91 + SkASSERT(alpha <= 255); 1.92 + if (count > 0) { 1.93 +#ifdef UNROLL 1.94 + if (count & 1) { 1.95 + *dst = SkBlendARGB32(*(src++), *dst, alpha); 1.96 + dst += 1; 1.97 + count -= 1; 1.98 + } 1.99 + 1.100 + const SkPMColor* SK_RESTRICT srcEnd = src + count; 1.101 + while (src != srcEnd) { 1.102 + *dst = SkBlendARGB32(*(src++), *dst, alpha); 1.103 + dst += 1; 1.104 + *dst = SkBlendARGB32(*(src++), *dst, alpha); 1.105 + dst += 1; 1.106 + } 1.107 +#else 1.108 + do { 1.109 + *dst = SkBlendARGB32(*src, *dst, alpha); 1.110 + src += 1; 1.111 + dst += 1; 1.112 + } while (--count > 0); 1.113 +#endif 1.114 + } 1.115 +} 1.116 + 1.117 +/////////////////////////////////////////////////////////////////////////////// 1.118 + 1.119 +static const SkBlitRow::Proc32 gDefault_Procs32[] = { 1.120 + S32_Opaque_BlitRow32, 1.121 + S32_Blend_BlitRow32, 1.122 + S32A_Opaque_BlitRow32, 1.123 + S32A_Blend_BlitRow32 1.124 +}; 1.125 + 1.126 +SkBlitRow::Proc32 SkBlitRow::Factory32(unsigned flags) { 1.127 + SkASSERT(flags < SK_ARRAY_COUNT(gDefault_Procs32)); 1.128 + // just so we don't crash 1.129 + flags &= kFlags32_Mask; 1.130 + 1.131 + SkBlitRow::Proc32 proc = PlatformProcs32(flags); 1.132 + if (NULL == proc) { 1.133 + proc = gDefault_Procs32[flags]; 1.134 + } 1.135 + SkASSERT(proc); 1.136 + return proc; 1.137 +} 1.138 + 1.139 +SkBlitRow::Proc32 SkBlitRow::ColorProcFactory() { 1.140 + SkBlitRow::ColorProc proc = PlatformColorProc(); 1.141 + if (NULL == proc) { 1.142 + proc = Color32; 1.143 + } 1.144 + SkASSERT(proc); 1.145 + return proc; 1.146 +} 1.147 + 1.148 +void SkBlitRow::Color32(SkPMColor* SK_RESTRICT dst, 1.149 + const SkPMColor* SK_RESTRICT src, 1.150 + int count, SkPMColor color) { 1.151 + if (count > 0) { 1.152 + if (0 == color) { 1.153 + if (src != dst) { 1.154 + memcpy(dst, src, count * sizeof(SkPMColor)); 1.155 + } 1.156 + return; 1.157 + } 1.158 + unsigned colorA = SkGetPackedA32(color); 1.159 + if (255 == colorA) { 1.160 + sk_memset32(dst, color, count); 1.161 + } else { 1.162 + unsigned scale = 256 - SkAlpha255To256(colorA); 1.163 + do { 1.164 + *dst = color + SkAlphaMulQ(*src, scale); 1.165 + src += 1; 1.166 + dst += 1; 1.167 + } while (--count); 1.168 + } 1.169 + } 1.170 +} 1.171 + 1.172 +template <size_t N> void assignLoop(SkPMColor* dst, SkPMColor color) { 1.173 + for (size_t i = 0; i < N; ++i) { 1.174 + *dst++ = color; 1.175 + } 1.176 +} 1.177 + 1.178 +static inline void assignLoop(SkPMColor dst[], SkPMColor color, int count) { 1.179 + while (count >= 4) { 1.180 + *dst++ = color; 1.181 + *dst++ = color; 1.182 + *dst++ = color; 1.183 + *dst++ = color; 1.184 + count -= 4; 1.185 + } 1.186 + if (count >= 2) { 1.187 + *dst++ = color; 1.188 + *dst++ = color; 1.189 + count -= 2; 1.190 + } 1.191 + if (count > 0) { 1.192 + *dst++ = color; 1.193 + } 1.194 +} 1.195 + 1.196 +void SkBlitRow::ColorRect32(SkPMColor* dst, int width, int height, 1.197 + size_t rowBytes, SkPMColor color) { 1.198 + if (width <= 0 || height <= 0 || 0 == color) { 1.199 + return; 1.200 + } 1.201 + 1.202 + // Just made up this value, since I saw it once in a SSE2 file. 1.203 + // We should consider writing some tests to find the optimimal break-point 1.204 + // (or query the Platform proc?) 1.205 + static const int MIN_WIDTH_FOR_SCANLINE_PROC = 32; 1.206 + 1.207 + bool isOpaque = (0xFF == SkGetPackedA32(color)); 1.208 + 1.209 + if (!isOpaque || width >= MIN_WIDTH_FOR_SCANLINE_PROC) { 1.210 + SkBlitRow::ColorProc proc = SkBlitRow::ColorProcFactory(); 1.211 + while (--height >= 0) { 1.212 + (*proc)(dst, dst, width, color); 1.213 + dst = (SkPMColor*) ((char*)dst + rowBytes); 1.214 + } 1.215 + } else { 1.216 + switch (width) { 1.217 + case 1: 1.218 + while (--height >= 0) { 1.219 + assignLoop<1>(dst, color); 1.220 + dst = (SkPMColor*) ((char*)dst + rowBytes); 1.221 + } 1.222 + break; 1.223 + case 2: 1.224 + while (--height >= 0) { 1.225 + assignLoop<2>(dst, color); 1.226 + dst = (SkPMColor*) ((char*)dst + rowBytes); 1.227 + } 1.228 + break; 1.229 + case 3: 1.230 + while (--height >= 0) { 1.231 + assignLoop<3>(dst, color); 1.232 + dst = (SkPMColor*) ((char*)dst + rowBytes); 1.233 + } 1.234 + break; 1.235 + default: 1.236 + while (--height >= 0) { 1.237 + assignLoop(dst, color, width); 1.238 + dst = (SkPMColor*) ((char*)dst + rowBytes); 1.239 + } 1.240 + break; 1.241 + } 1.242 + } 1.243 +} 1.244 + 1.245 +SkBlitRow::ColorRectProc SkBlitRow::ColorRectProcFactory() { 1.246 + SkBlitRow::ColorRectProc proc = PlatformColorRectProcFactory(); 1.247 + if (NULL == proc) { 1.248 + proc = ColorRect32; 1.249 + } 1.250 + SkASSERT(proc); 1.251 + return proc; 1.252 +}