SkOpts.cpp revision f96bee384dea60a4e96035878e2671cd49d3b406
1/* 2 * Copyright 2015 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 "SkOnce.h" 9#include "SkOpts.h" 10#include "SkXfermode_opts.h" 11 12#if defined(SK_CPU_X86) 13 #if defined(SK_BUILD_FOR_WIN32) 14 #include <intrin.h> 15 static void cpuid(uint32_t abcd[4]) { __cpuid((int*)abcd, 1); } 16 #else 17 #include <cpuid.h> 18 static void cpuid(uint32_t abcd[4]) { __get_cpuid(1, abcd+0, abcd+1, abcd+2, abcd+3); } 19 #endif 20#elif !defined(SK_ARM_HAS_NEON) && defined(SK_CPU_ARM32) && defined(SK_BUILD_FOR_ANDROID) 21 #include <cpu-features.h> 22#endif 23 24namespace portable { // This helps identify methods from this file when debugging / profiling. 25 26static float rsqrt(float x) { 27 // Get initial estimate. 28 int i = *SkTCast<int*>(&x); 29 i = 0x5F1FFFF9 - (i>>1); 30 float estimate = *SkTCast<float*>(&i); 31 32 // One step of Newton's method to refine. 33 const float estimate_sq = estimate*estimate; 34 estimate *= 0.703952253f*(2.38924456f-x*estimate_sq); 35 return estimate; 36} 37 38template <typename T> 39static void memsetT(T dst[], T val, int n) { while (n --> 0) { *dst++ = val; } } 40 41} // namespace portable 42 43namespace SkOpts { 44 // Define default function pointer values here... 45 decltype(rsqrt) rsqrt = portable::rsqrt; 46 decltype(memset16) memset16 = portable::memsetT<uint16_t>; 47 decltype(memset32) memset32 = portable::memsetT<uint32_t>; 48 decltype(create_xfermode) create_xfermode = SkCreate4pxXfermode; 49 50 // Each Init_foo() is defined in src/opts/SkOpts_foo.cpp. 51 void Init_sse2(); 52 void Init_ssse3(); 53 void Init_sse41(); 54 void Init_neon(); 55 //TODO: _dsp2, _armv7, _armv8, _x86, _x86_64, _sse42, _avx, avx2, ... ? 56 57 static void init() { 58 // TODO: Chrome's not linking _sse* opts on iOS simulator builds. Bug or feature? 59 #if defined(SK_CPU_X86) && !defined(SK_BUILD_FOR_IOS) 60 uint32_t abcd[] = {0,0,0,0}; 61 cpuid(abcd); 62 if (abcd[3] & (1<<26)) { Init_sse2(); } 63 if (abcd[2] & (1<< 9)) { Init_ssse3(); } 64 if (abcd[2] & (1<<19)) { Init_sse41(); } 65 #elif defined(SK_ARM_HAS_NEON) 66 Init_neon(); 67 #elif defined(SK_CPU_ARM32) && defined(SK_BUILD_FOR_ANDROID) 68 if (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) { Init_neon(); } 69 #endif 70 } 71 72 SK_DECLARE_STATIC_ONCE(gInitOnce); 73 void Init() { SkOnce(&gInitOnce, init); } 74 75#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 76 static struct AutoInit { 77 AutoInit() { Init(); } 78 } gAutoInit; 79#endif 80} 81