gfx/skia/trunk/src/core/SkUtilsArm.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1
michael@0 2 /*
michael@0 3 * Copyright 2012 The Android Open Source Project
michael@0 4 *
michael@0 5 * Use of this source code is governed by a BSD-style license that can be
michael@0 6 * found in the LICENSE file.
michael@0 7 */
michael@0 8
michael@0 9 #include "SkUtilsArm.h"
michael@0 10
michael@0 11 #if SK_ARM_NEON_IS_DYNAMIC
michael@0 12
michael@0 13 #include <unistd.h>
michael@0 14 #include <fcntl.h>
michael@0 15 #include <errno.h>
michael@0 16 #include <string.h>
michael@0 17 #include <pthread.h>
michael@0 18
michael@0 19 // Set USE_ANDROID_NDK_CPU_FEATURES to use the Android NDK's
michael@0 20 // cpu-features helper library to detect NEON at runtime. See
michael@0 21 // http://crbug.com/164154 to see why this is needed in Chromium
michael@0 22 // for Android.
michael@0 23 #if !defined(USE_ANDROID_NDK_CPU_FEATURES)
michael@0 24 # if defined(SK_BUILD_FOR_ANDROID)
michael@0 25 # define USE_ANDROID_NDK_CPU_FEATURES 1
michael@0 26 # else
michael@0 27 # define USE_ANDROID_NDK_CPU_FEATURES 0
michael@0 28 # endif
michael@0 29 #endif
michael@0 30
michael@0 31 #if USE_ANDROID_NDK_CPU_FEATURES
michael@0 32 # include <cpu-features.h>
michael@0 33 #endif
michael@0 34
michael@0 35 // Set NEON_DEBUG to 1 to allow debugging of the CPU features probing.
michael@0 36 // For now, we always set it for SK_DEBUG builds.
michael@0 37 #ifdef SK_DEBUG
michael@0 38 # define NEON_DEBUG 1
michael@0 39 #else
michael@0 40 # define NEON_DEBUG 0
michael@0 41 #endif
michael@0 42
michael@0 43 #if NEON_DEBUG
michael@0 44 # ifdef SK_BUILD_FOR_ANDROID
michael@0 45 // used to declare PROP_VALUE_MAX and __system_property_get()
michael@0 46 # include <sys/system_properties.h>
michael@0 47 # endif
michael@0 48 #endif
michael@0 49
michael@0 50 // A function used to determine at runtime if the target CPU supports
michael@0 51 // the ARM NEON instruction set. This implementation is Linux-specific.
michael@0 52 static bool sk_cpu_arm_check_neon(void) {
michael@0 53 bool result = false;
michael@0 54
michael@0 55 #if NEON_DEBUG
michael@0 56 // Allow forcing the mode through the environment during debugging.
michael@0 57 # ifdef SK_BUILD_FOR_ANDROID
michael@0 58 // On Android, we use a system property
michael@0 59 # define PROP_NAME "debug.skia.arm_neon_mode"
michael@0 60 char prop[PROP_VALUE_MAX];
michael@0 61 if (__system_property_get(PROP_NAME, prop) > 0) {
michael@0 62 # else
michael@0 63 # define PROP_NAME "SKIA_ARM_NEON_MODE"
michael@0 64 // On ARM Linux, we use an environment variable
michael@0 65 const char* prop = getenv(PROP_NAME);
michael@0 66 if (prop != NULL) {
michael@0 67 # endif
michael@0 68 SkDebugf("%s: %s", PROP_NAME, prop);
michael@0 69 if (!strcmp(prop, "1")) {
michael@0 70 SkDebugf("Forcing ARM Neon mode to full!\n");
michael@0 71 return true;
michael@0 72 }
michael@0 73 if (!strcmp(prop, "0")) {
michael@0 74 SkDebugf("Disabling ARM NEON mode\n");
michael@0 75 return false;
michael@0 76 }
michael@0 77 }
michael@0 78 SkDebugf("Running dynamic CPU feature detection\n");
michael@0 79 #endif
michael@0 80
michael@0 81 #if USE_ANDROID_NDK_CPU_FEATURES
michael@0 82
michael@0 83 result = (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
michael@0 84
michael@0 85 #else // USE_ANDROID_NDK_CPU_FEATURES
michael@0 86
michael@0 87 // There is no user-accessible CPUID instruction on ARM that we can use.
michael@0 88 // Instead, we must parse /proc/cpuinfo and look for the 'neon' feature.
michael@0 89 // For example, here's a typical output (Nexus S running ICS 4.0.3):
michael@0 90 /*
michael@0 91 Processor : ARMv7 Processor rev 2 (v7l)
michael@0 92 BogoMIPS : 994.65
michael@0 93 Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3
michael@0 94 CPU implementer : 0x41
michael@0 95 CPU architecture: 7
michael@0 96 CPU variant : 0x2
michael@0 97 CPU part : 0xc08
michael@0 98 CPU revision : 2
michael@0 99
michael@0 100 Hardware : herring
michael@0 101 Revision : 000b
michael@0 102 Serial : 3833c77d6dc000ec
michael@0 103 */
michael@0 104 char buffer[4096];
michael@0 105
michael@0 106 // If we fail any of the following, assume we don't have NEON instructions
michael@0 107 // This allows us to return immediately in case of error.
michael@0 108 result = false;
michael@0 109
michael@0 110 do {
michael@0 111 // open /proc/cpuinfo
michael@0 112 int fd = TEMP_FAILURE_RETRY(open("/proc/cpuinfo", O_RDONLY));
michael@0 113 if (fd < 0) {
michael@0 114 SkDebugf("Could not open /proc/cpuinfo: %s\n", strerror(errno));
michael@0 115 break;
michael@0 116 }
michael@0 117
michael@0 118 // Read the file. To simplify our search, we're going to place two
michael@0 119 // sentinel '\n' characters: one at the start of the buffer, and one at
michael@0 120 // the end. This means we reserve the first and last buffer bytes.
michael@0 121 buffer[0] = '\n';
michael@0 122 int size = TEMP_FAILURE_RETRY(read(fd, buffer+1, sizeof(buffer)-2));
michael@0 123 close(fd);
michael@0 124
michael@0 125 if (size < 0) { // should not happen
michael@0 126 SkDebugf("Could not read /proc/cpuinfo: %s\n", strerror(errno));
michael@0 127 break;
michael@0 128 }
michael@0 129
michael@0 130 SkDebugf("START /proc/cpuinfo:\n%.*s\nEND /proc/cpuinfo\n",
michael@0 131 size, buffer+1);
michael@0 132
michael@0 133 // Compute buffer limit, and place final sentinel
michael@0 134 char* buffer_end = buffer + 1 + size;
michael@0 135 buffer_end[0] = '\n';
michael@0 136
michael@0 137 // Now, find a line that starts with "Features", i.e. look for
michael@0 138 // '\nFeatures ' in our buffer.
michael@0 139 const char features[] = "\nFeatures\t";
michael@0 140 const size_t features_len = sizeof(features)-1;
michael@0 141
michael@0 142 char* line = (char*) memmem(buffer, buffer_end - buffer,
michael@0 143 features, features_len);
michael@0 144 if (line == NULL) { // Weird, no Features line, bad kernel?
michael@0 145 SkDebugf("Could not find a line starting with 'Features'"
michael@0 146 "in /proc/cpuinfo ?\n");
michael@0 147 break;
michael@0 148 }
michael@0 149
michael@0 150 line += features_len; // Skip the "\nFeatures\t" prefix
michael@0 151
michael@0 152 // Find the end of the current line
michael@0 153 char* line_end = (char*) memchr(line, '\n', buffer_end - line);
michael@0 154 if (line_end == NULL)
michael@0 155 line_end = buffer_end;
michael@0 156
michael@0 157 // Now find an instance of 'neon' in the flags list. We want to
michael@0 158 // ensure it's only 'neon' and not something fancy like 'noneon'
michael@0 159 // so check that it follows a space.
michael@0 160 const char neon[] = " neon";
michael@0 161 const size_t neon_len = sizeof(neon)-1;
michael@0 162 const char* flag = (const char*) memmem(line, line_end - line,
michael@0 163 neon, neon_len);
michael@0 164 if (flag == NULL)
michael@0 165 break;
michael@0 166
michael@0 167 // Ensure it is followed by a space or a newline.
michael@0 168 if (flag[neon_len] != ' ' && flag[neon_len] != '\n')
michael@0 169 break;
michael@0 170
michael@0 171 // Fine, we support Arm NEON !
michael@0 172 result = true;
michael@0 173
michael@0 174 } while (0);
michael@0 175
michael@0 176 #endif // USE_ANDROID_NDK_CPU_FEATURES
michael@0 177
michael@0 178 if (result) {
michael@0 179 SkDebugf("Device supports ARM NEON instructions!\n");
michael@0 180 } else {
michael@0 181 SkDebugf("Device does NOT support ARM NEON instructions!\n");
michael@0 182 }
michael@0 183 return result;
michael@0 184 }
michael@0 185
michael@0 186 static pthread_once_t sOnce;
michael@0 187 static bool sHasArmNeon;
michael@0 188
michael@0 189 // called through pthread_once()
michael@0 190 void sk_cpu_arm_probe_features(void) {
michael@0 191 sHasArmNeon = sk_cpu_arm_check_neon();
michael@0 192 }
michael@0 193
michael@0 194 bool sk_cpu_arm_has_neon(void) {
michael@0 195 pthread_once(&sOnce, sk_cpu_arm_probe_features);
michael@0 196 return sHasArmNeon;
michael@0 197 }
michael@0 198
michael@0 199 #endif // SK_ARM_NEON_IS_DYNAMIC

mercurial