| Index: webrtc/base/systeminfo.cc | 
| diff --git a/webrtc/base/systeminfo.cc b/webrtc/base/systeminfo.cc | 
| index 6d8d5ba7514d0107c4911a1cdb3143274038f05f..1dc6a682e90e7ab88a092cb665924424d421c543 100644 | 
| --- a/webrtc/base/systeminfo.cc | 
| +++ b/webrtc/base/systeminfo.cc | 
| @@ -12,6 +12,7 @@ | 
|  | 
| #if defined(WEBRTC_WIN) | 
| #include <winsock2.h> | 
| +#include <windows.h> | 
| #ifndef EXCLUDE_D3D9 | 
| #include <d3d9.h> | 
| #endif | 
| @@ -26,14 +27,6 @@ | 
| #include <sys/sysctl.h> | 
| #endif | 
|  | 
| -#if defined(WEBRTC_WIN) | 
| -#include "webrtc/base/scoped_ptr.h" | 
| -#include "webrtc/base/win32.h" | 
| -#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) | 
| -#include "webrtc/base/macconversion.h" | 
| -#elif defined(WEBRTC_LINUX) | 
| -#include "webrtc/base/linux.h" | 
| -#endif | 
| #include "webrtc/base/common.h" | 
| #include "webrtc/base/logging.h" | 
| #include "webrtc/base/stringutils.h" | 
| @@ -41,47 +34,7 @@ | 
| namespace rtc { | 
|  | 
| // See Also: http://msdn.microsoft.com/en-us/library/ms683194(v=vs.85).aspx | 
| -#if defined(WEBRTC_WIN) | 
| -typedef BOOL (WINAPI *LPFN_GLPI)( | 
| -    PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, | 
| -    PDWORD); | 
| - | 
| -static void GetProcessorInformation(int* physical_cpus, int* cache_size) { | 
| -  // GetLogicalProcessorInformation() is available on Windows XP SP3 and beyond. | 
| -  LPFN_GLPI glpi = reinterpret_cast<LPFN_GLPI>(GetProcAddress( | 
| -      GetModuleHandle(L"kernel32"), | 
| -      "GetLogicalProcessorInformation")); | 
| -  if (NULL == glpi) { | 
| -    return; | 
| -  } | 
| -  // Determine buffer size, allocate and get processor information. | 
| -  // Size can change between calls (unlikely), so a loop is done. | 
| -  DWORD return_length = 0; | 
| -  scoped_ptr<SYSTEM_LOGICAL_PROCESSOR_INFORMATION[]> infos; | 
| -  while (!glpi(infos.get(), &return_length)) { | 
| -    if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { | 
| -      infos.reset(new SYSTEM_LOGICAL_PROCESSOR_INFORMATION[ | 
| -          return_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)]); | 
| -    } else { | 
| -      return; | 
| -    } | 
| -  } | 
| -  *physical_cpus = 0; | 
| -  *cache_size = 0; | 
| -  for (size_t i = 0; | 
| -      i < return_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ++i) { | 
| -    if (infos[i].Relationship == RelationProcessorCore) { | 
| -      ++*physical_cpus; | 
| -    } else if (infos[i].Relationship == RelationCache) { | 
| -      int next_cache_size = static_cast<int>(infos[i].Cache.Size); | 
| -      if (next_cache_size >= *cache_size) { | 
| -        *cache_size = next_cache_size; | 
| -      } | 
| -    } | 
| -  } | 
| -  return; | 
| -} | 
| -#else | 
| +#if !defined(WEBRTC_WIN) | 
| // TODO(fbarchard): Use gcc 4.4 provided cpuid intrinsic | 
| // 32 bit fpic requires ebx be preserved | 
| #if (defined(__pic__) || defined(__APPLE__)) && defined(__i386__) | 
| @@ -103,134 +56,64 @@ static inline void __cpuid(int cpu_info[4], int info_type) { | 
| );  // NOLINT | 
| } | 
| #endif | 
| -#endif  // WEBRTC_WIN | 
| +#endif  // WEBRTC_WIN | 
|  | 
| -// Note(fbarchard): | 
| -// Family and model are extended family and extended model.  8 bits each. | 
| -SystemInfo::SystemInfo() | 
| -    : physical_cpus_(1), logical_cpus_(1), cache_size_(0), | 
| -      cpu_family_(0), cpu_model_(0), cpu_stepping_(0), | 
| -      cpu_speed_(0), memory_(0) { | 
| -  // Initialize the basic information. | 
| -#if defined(__arm__) || defined(_M_ARM) | 
| -  cpu_arch_ = SI_ARCH_ARM; | 
| -#elif defined(__x86_64__) || defined(_M_X64) | 
| -  cpu_arch_ = SI_ARCH_X64; | 
| -#elif defined(__i386__) || defined(_M_IX86) | 
| -  cpu_arch_ = SI_ARCH_X86; | 
| -#else | 
| -  cpu_arch_ = SI_ARCH_UNKNOWN; | 
| -#endif | 
| +static int DetectNumberOfCores() { | 
| +  // We fall back on assuming a single core in case of errors. | 
| +  int number_of_cores = 1; | 
|  | 
| #if defined(WEBRTC_WIN) | 
| SYSTEM_INFO si; | 
| GetSystemInfo(&si); | 
| -  logical_cpus_ = si.dwNumberOfProcessors; | 
| -  GetProcessorInformation(&physical_cpus_, &cache_size_); | 
| -  if (physical_cpus_ <= 0) { | 
| -    physical_cpus_ = logical_cpus_; | 
| -  } | 
| -  cpu_family_ = si.wProcessorLevel; | 
| -  cpu_model_ = si.wProcessorRevision >> 8; | 
| -  cpu_stepping_ = si.wProcessorRevision & 0xFF; | 
| +  number_of_cores = static_cast<int>(si.dwNumberOfProcessors); | 
| +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID) | 
| +  number_of_cores = static_cast<int>(sysconf(_SC_NPROCESSORS_ONLN)); | 
| #elif defined(WEBRTC_MAC) | 
| -  uint32_t sysctl_value; | 
| -  size_t length = sizeof(sysctl_value); | 
| -  if (!sysctlbyname("hw.physicalcpu_max", &sysctl_value, &length, NULL, 0)) { | 
| -    physical_cpus_ = static_cast<int>(sysctl_value); | 
| -  } | 
| -  length = sizeof(sysctl_value); | 
| -  if (!sysctlbyname("hw.logicalcpu_max", &sysctl_value, &length, NULL, 0)) { | 
| -    logical_cpus_ = static_cast<int>(sysctl_value); | 
| -  } | 
| -  uint64_t sysctl_value64; | 
| -  length = sizeof(sysctl_value64); | 
| -  if (!sysctlbyname("hw.l3cachesize", &sysctl_value64, &length, NULL, 0)) { | 
| -    cache_size_ = static_cast<int>(sysctl_value64); | 
| -  } | 
| -  if (!cache_size_) { | 
| -    length = sizeof(sysctl_value64); | 
| -    if (!sysctlbyname("hw.l2cachesize", &sysctl_value64, &length, NULL, 0)) { | 
| -      cache_size_ = static_cast<int>(sysctl_value64); | 
| -    } | 
| -  } | 
| -  length = sizeof(sysctl_value); | 
| -  if (!sysctlbyname("machdep.cpu.family", &sysctl_value, &length, NULL, 0)) { | 
| -    cpu_family_ = static_cast<int>(sysctl_value); | 
| -  } | 
| -  length = sizeof(sysctl_value); | 
| -  if (!sysctlbyname("machdep.cpu.model", &sysctl_value, &length, NULL, 0)) { | 
| -    cpu_model_ = static_cast<int>(sysctl_value); | 
| -  } | 
| -  length = sizeof(sysctl_value); | 
| -  if (!sysctlbyname("machdep.cpu.stepping", &sysctl_value, &length, NULL, 0)) { | 
| -    cpu_stepping_ = static_cast<int>(sysctl_value); | 
| -  } | 
| -#elif defined(__native_client__) | 
| -  // TODO(ryanpetrie): Implement this via PPAPI when it's available. | 
| -#else  // WEBRTC_LINUX | 
| -  ProcCpuInfo proc_info; | 
| -  if (proc_info.LoadFromSystem()) { | 
| -    proc_info.GetNumCpus(&logical_cpus_); | 
| -    proc_info.GetNumPhysicalCpus(&physical_cpus_); | 
| -    proc_info.GetCpuFamily(&cpu_family_); | 
| -#if defined(CPU_X86) | 
| -    // These values only apply to x86 systems. | 
| -    proc_info.GetSectionIntValue(0, "model", &cpu_model_); | 
| -    proc_info.GetSectionIntValue(0, "stepping", &cpu_stepping_); | 
| -    proc_info.GetSectionIntValue(0, "cpu MHz", &cpu_speed_); | 
| -    proc_info.GetSectionIntValue(0, "cache size", &cache_size_); | 
| -    cache_size_ *= 1024; | 
| -#endif | 
| -  } | 
| -  // ProcCpuInfo reads cpu speed from "cpu MHz" under /proc/cpuinfo. | 
| -  // But that number is a moving target which can change on-the-fly according to | 
| -  // many factors including system workload. | 
| -  // See /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors. | 
| -  // The one in /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq is more | 
| -  // accurate. We use it as our cpu speed when it is available. | 
| -  // cpuinfo_max_freq is measured in KHz and requires conversion to MHz. | 
| -  int max_freq = rtc::ReadCpuMaxFreq(); | 
| -  if (max_freq > 0) { | 
| -    cpu_speed_ = max_freq / 1000; | 
| -  } | 
| -#endif | 
| -// For L2 CacheSize see also | 
| -// http://www.flounder.com/cpuid_explorer2.htm#CPUID(0x800000006) | 
| -#ifdef CPU_X86 | 
| -  if (cache_size_ == 0) { | 
| -    int cpu_info[4]; | 
| -    __cpuid(cpu_info, 0x80000000);  // query maximum extended cpuid function. | 
| -    if (static_cast<uint32>(cpu_info[0]) >= 0x80000006) { | 
| -      __cpuid(cpu_info, 0x80000006); | 
| -      cache_size_ = (cpu_info[2] >> 16) * 1024; | 
| -    } | 
| +  int name[] = {CTL_HW, HW_AVAILCPU}; | 
| +  size_t size = sizeof(number_of_cores); | 
| +  if (0 != sysctl(name, 2, &number_of_cores, &size, NULL, 0)) { | 
| +    LOG(LS_ERROR) << "Failed to get number of cores"; | 
| +    number_of_cores = 1; | 
| } | 
| +#else | 
| +  LOG(LS_ERROR) << "No function to get number of cores"; | 
| #endif | 
| + | 
| +  LOG(LS_INFO) << "Available number of cores: " << number_of_cores; | 
| + | 
| +  return number_of_cores; | 
| +} | 
| + | 
| +// Statically cache the number of system cores available since if the process | 
| +// is running in a sandbox, we may only be able to read the value once (before | 
| +// the sandbox is initialized) and not thereafter. | 
| +// For more information see crbug.com/176522. | 
| +int SystemInfo::logical_cpus_ = 0; | 
| + | 
| +SystemInfo::SystemInfo() { | 
| } | 
|  | 
| // Return the number of cpu threads available to the system. | 
| +// static | 
| int SystemInfo::GetMaxCpus() { | 
| +  if (!logical_cpus_) | 
| +    logical_cpus_ = DetectNumberOfCores(); | 
| return logical_cpus_; | 
| } | 
|  | 
| -// Return the number of cpu cores available to the system. | 
| -int SystemInfo::GetMaxPhysicalCpus() { | 
| -  return physical_cpus_; | 
| -} | 
| - | 
| // Return the number of cpus available to the process.  Since affinity can be | 
| // changed on the fly, do not cache this value. | 
| // Can be affected by heat. | 
| int SystemInfo::GetCurCpus() { | 
| -  int cur_cpus; | 
| +  int cur_cpus = 0; | 
| #if defined(WEBRTC_WIN) | 
| -  DWORD_PTR process_mask, system_mask; | 
| +  DWORD_PTR process_mask = 0; | 
| +  DWORD_PTR system_mask = 0; | 
| ::GetProcessAffinityMask(::GetCurrentProcess(), &process_mask, &system_mask); | 
| -  for (cur_cpus = 0; process_mask; ++cur_cpus) { | 
| -    // Sparse-ones algorithm. There are slightly faster methods out there but | 
| -    // they are unintuitive and won't make a difference on a single dword. | 
| -    process_mask &= (process_mask - 1); | 
| +  for (int i = 0; i < sizeof(DWORD_PTR) * 8; ++i) { | 
| +    if (process_mask & 1) | 
| +      ++cur_cpus; | 
| +    process_mask >>= 1; | 
| } | 
| #elif defined(WEBRTC_MAC) | 
| uint32_t sysctl_value; | 
| @@ -239,285 +122,92 @@ int SystemInfo::GetCurCpus() { | 
| cur_cpus = !error ? static_cast<int>(sysctl_value) : 1; | 
| #else | 
| // Linux, Solaris, WEBRTC_ANDROID | 
| -  cur_cpus = static_cast<int>(sysconf(_SC_NPROCESSORS_ONLN)); | 
| +  cur_cpus = GetMaxCpus(); | 
| #endif | 
| return cur_cpus; | 
| } | 
|  | 
| // Return the type of this CPU. | 
| SystemInfo::Architecture SystemInfo::GetCpuArchitecture() { | 
| -  return cpu_arch_; | 
| +#if defined(__arm__) || defined(_M_ARM) | 
| +  return SI_ARCH_ARM; | 
| +#elif defined(__x86_64__) || defined(_M_X64) | 
| +  return SI_ARCH_X64; | 
| +#elif defined(__i386__) || defined(_M_IX86) | 
| +  return SI_ARCH_X86; | 
| +#else | 
| +  return SI_ARCH_UNKNOWN; | 
| +#endif | 
| } | 
|  | 
| // Returns the vendor string from the cpu, e.g. "GenuineIntel", "AuthenticAMD". | 
| // See "Intel Processor Identification and the CPUID Instruction" | 
| // (Intel document number: 241618) | 
| std::string SystemInfo::GetCpuVendor() { | 
| -  if (cpu_vendor_.empty()) { | 
| #if defined(CPU_X86) | 
| -    int cpu_info[4]; | 
| -    __cpuid(cpu_info, 0); | 
| -    cpu_info[0] = cpu_info[1];  // Reorder output | 
| -    cpu_info[1] = cpu_info[3]; | 
| -    // cpu_info[2] = cpu_info[2];  // Avoid -Werror=self-assign | 
| -    cpu_info[3] = 0; | 
| -    cpu_vendor_ = std::string(reinterpret_cast<char*>(&cpu_info[0])); | 
| +  int cpu_info[4]; | 
| +  __cpuid(cpu_info, 0); | 
| +  cpu_info[0] = cpu_info[1];  // Reorder output | 
| +  cpu_info[1] = cpu_info[3]; | 
| +  // cpu_info[2] = cpu_info[2];  // Avoid -Werror=self-assign | 
| +  cpu_info[3] = 0; | 
| +  return std::string(reinterpret_cast<char*>(&cpu_info[0])); | 
| #elif defined(CPU_ARM) | 
| -    cpu_vendor_ = std::string("ARM"); | 
| +  return "ARM"; | 
| #else | 
| -    cpu_vendor_ = std::string("Undefined"); | 
| -#endif | 
| -  } | 
| -  return cpu_vendor_; | 
| -} | 
| - | 
| -int SystemInfo::GetCpuCacheSize() { | 
| -  return cache_size_; | 
| -} | 
| - | 
| -// Return the "family" of this CPU. | 
| -int SystemInfo::GetCpuFamily() { | 
| -  return cpu_family_; | 
| -} | 
| - | 
| -// Return the "model" of this CPU. | 
| -int SystemInfo::GetCpuModel() { | 
| -  return cpu_model_; | 
| -} | 
| - | 
| -// Return the "stepping" of this CPU. | 
| -int SystemInfo::GetCpuStepping() { | 
| -  return cpu_stepping_; | 
| -} | 
| - | 
| -// Return the clockrate of the primary processor in Mhz.  This value can be | 
| -// cached.  Returns -1 on error. | 
| -int SystemInfo::GetMaxCpuSpeed() { | 
| -  if (cpu_speed_) { | 
| -    return cpu_speed_; | 
| -  } | 
| -#if defined(WEBRTC_WIN) | 
| -  HKEY key; | 
| -  static const WCHAR keyName[] = | 
| -      L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"; | 
| - | 
| -  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName , 0, KEY_QUERY_VALUE, &key) | 
| -      == ERROR_SUCCESS) { | 
| -    DWORD data, len; | 
| -    len = sizeof(data); | 
| - | 
| -    if (RegQueryValueEx(key, L"~Mhz", 0, 0, reinterpret_cast<LPBYTE>(&data), | 
| -                        &len) == ERROR_SUCCESS) { | 
| -      cpu_speed_ = data; | 
| -    } else { | 
| -      LOG(LS_WARNING) << "Failed to query registry value HKLM\\" << keyName | 
| -                      << "\\~Mhz"; | 
| -      cpu_speed_ = -1; | 
| -    } | 
| - | 
| -    RegCloseKey(key); | 
| -  } else { | 
| -    LOG(LS_WARNING) << "Failed to open registry key HKLM\\" << keyName; | 
| -    cpu_speed_ = -1; | 
| -  } | 
| -#elif defined(WEBRTC_MAC) | 
| -  uint64_t sysctl_value; | 
| -  size_t length = sizeof(sysctl_value); | 
| -  int error = sysctlbyname("hw.cpufrequency_max", &sysctl_value, &length, | 
| -                           NULL, 0); | 
| -  cpu_speed_ = !error ? static_cast<int>(sysctl_value/1000000) : -1; | 
| -#else | 
| -  // TODO(fbarchard): Implement using proc/cpuinfo | 
| -  cpu_speed_ = 0; | 
| -#endif | 
| -  return cpu_speed_; | 
| -} | 
| - | 
| -// Dynamically check the current clockrate, which could be reduced because of | 
| -// powersaving profiles.  Eventually for windows we want to query WMI for | 
| -// root\WMI::ProcessorPerformance.InstanceName="Processor_Number_0".frequency | 
| -int SystemInfo::GetCurCpuSpeed() { | 
| -#if defined(WEBRTC_WIN) | 
| -  // TODO(fbarchard): Add WMI check, requires COM initialization | 
| -  // NOTE(fbarchard): Testable on Sandy Bridge. | 
| -  return GetMaxCpuSpeed(); | 
| -#elif defined(WEBRTC_MAC) | 
| -  uint64_t sysctl_value; | 
| -  size_t length = sizeof(sysctl_value); | 
| -  int error = sysctlbyname("hw.cpufrequency", &sysctl_value, &length, NULL, 0); | 
| -  return !error ? static_cast<int>(sysctl_value/1000000) : GetMaxCpuSpeed(); | 
| -#else  // WEBRTC_LINUX | 
| -  // TODO(fbarchard): Use proc/cpuinfo for Cur speed on Linux. | 
| -  return GetMaxCpuSpeed(); | 
| +  return "Undefined"; | 
| #endif | 
| } | 
|  | 
| // Returns the amount of installed physical memory in Bytes.  Cacheable. | 
| // Returns -1 on error. | 
| int64 SystemInfo::GetMemorySize() { | 
| -  if (memory_) { | 
| -    return memory_; | 
| -  } | 
| +  int64 memory = -1; | 
|  | 
| #if defined(WEBRTC_WIN) | 
| MEMORYSTATUSEX status = {0}; | 
| status.dwLength = sizeof(status); | 
|  | 
| if (GlobalMemoryStatusEx(&status)) { | 
| -    memory_ = status.ullTotalPhys; | 
| +    memory = status.ullTotalPhys; | 
| } else { | 
| LOG_GLE(LS_WARNING) << "GlobalMemoryStatusEx failed."; | 
| -    memory_ = -1; | 
| } | 
|  | 
| #elif defined(WEBRTC_MAC) | 
| -  size_t len = sizeof(memory_); | 
| -  int error = sysctlbyname("hw.memsize", &memory_, &len, NULL, 0); | 
| -  if (error || memory_ == 0) { | 
| -    memory_ = -1; | 
| -  } | 
| +  size_t len = sizeof(memory); | 
| +  int error = sysctlbyname("hw.memsize", &memory, &len, NULL, 0); | 
| +  if (error || memory == 0) | 
| +    memory = -1; | 
| #else  // WEBRTC_LINUX | 
| -  memory_ = static_cast<int64>(sysconf(_SC_PHYS_PAGES)) * | 
| +  memory = static_cast<int64>(sysconf(_SC_PHYS_PAGES)) * | 
| static_cast<int64>(sysconf(_SC_PAGESIZE)); | 
| -  if (memory_ < 0) { | 
| +  if (memory < 0) { | 
| LOG(LS_WARNING) << "sysconf(_SC_PHYS_PAGES) failed." | 
| << "sysconf(_SC_PHYS_PAGES) " << sysconf(_SC_PHYS_PAGES) | 
| << "sysconf(_SC_PAGESIZE) " << sysconf(_SC_PAGESIZE); | 
| -    memory_ = -1; | 
| +    memory = -1; | 
| } | 
| #endif | 
|  | 
| -  return memory_; | 
| +  return memory; | 
| } | 
|  | 
| - | 
| // Return the name of the machine model we are currently running on. | 
| // This is a human readable string that consists of the name and version | 
| // number of the hardware, i.e 'MacBookAir1,1'. Returns an empty string if | 
| -// model can not be determined. The string is cached for subsequent calls. | 
| +// model can not be determined. | 
| std::string SystemInfo::GetMachineModel() { | 
| -  if (!machine_model_.empty()) { | 
| -    return machine_model_; | 
| -  } | 
| - | 
| #if defined(WEBRTC_MAC) | 
| char buffer[128]; | 
| size_t length = sizeof(buffer); | 
| int error = sysctlbyname("hw.model", buffer, &length, NULL, 0); | 
| -  if (!error) { | 
| -    machine_model_.assign(buffer, length - 1); | 
| -  } else { | 
| -    machine_model_.clear(); | 
| -  } | 
| +  if (!error) | 
| +    return std::string(buffer, length - 1); | 
| +  return std::string(); | 
| #else | 
| -  machine_model_ = "Not available"; | 
| +  return "Not available"; | 
| #endif | 
| - | 
| -  return machine_model_; | 
| } | 
|  | 
| -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) | 
| -// Helper functions to query IOKit for video hardware properties. | 
| -static CFTypeRef SearchForProperty(io_service_t port, CFStringRef name) { | 
| -  return IORegistryEntrySearchCFProperty(port, kIOServicePlane, | 
| -      name, kCFAllocatorDefault, | 
| -      kIORegistryIterateRecursively | kIORegistryIterateParents); | 
| -} | 
| - | 
| -static void GetProperty(io_service_t port, CFStringRef name, int* value) { | 
| -  if (!value) return; | 
| -  CFTypeRef ref = SearchForProperty(port, name); | 
| -  if (ref) { | 
| -    CFTypeID refType = CFGetTypeID(ref); | 
| -    if (CFNumberGetTypeID() == refType) { | 
| -      CFNumberRef number = reinterpret_cast<CFNumberRef>(ref); | 
| -      p_convertCFNumberToInt(number, value); | 
| -    } else if (CFDataGetTypeID() == refType) { | 
| -      CFDataRef data = reinterpret_cast<CFDataRef>(ref); | 
| -      if (CFDataGetLength(data) == sizeof(UInt32)) { | 
| -        *value = *reinterpret_cast<const UInt32*>(CFDataGetBytePtr(data)); | 
| -      } | 
| -    } | 
| -    CFRelease(ref); | 
| -  } | 
| -} | 
| - | 
| -static void GetProperty(io_service_t port, CFStringRef name, | 
| -                        std::string* value) { | 
| -  if (!value) return; | 
| -  CFTypeRef ref = SearchForProperty(port, name); | 
| -  if (ref) { | 
| -    CFTypeID refType = CFGetTypeID(ref); | 
| -    if (CFStringGetTypeID() == refType) { | 
| -      CFStringRef stringRef = reinterpret_cast<CFStringRef>(ref); | 
| -      p_convertHostCFStringRefToCPPString(stringRef, *value); | 
| -    } else if (CFDataGetTypeID() == refType) { | 
| -      CFDataRef dataRef = reinterpret_cast<CFDataRef>(ref); | 
| -      *value = std::string(reinterpret_cast<const char*>( | 
| -          CFDataGetBytePtr(dataRef)), CFDataGetLength(dataRef)); | 
| -    } | 
| -    CFRelease(ref); | 
| -  } | 
| -} | 
| -#endif | 
| - | 
| -SystemInfo::GpuInfo::GpuInfo() : vendor_id(0), device_id(0) { | 
| -} | 
| - | 
| -SystemInfo::GpuInfo::~GpuInfo() = default; | 
| - | 
| -// Fills a struct with information on the graphics adapater and returns true | 
| -// iff successful. | 
| -bool SystemInfo::GetGpuInfo(GpuInfo *info) { | 
| -  if (!info) return false; | 
| -#if defined(WEBRTC_WIN) && !defined(EXCLUDE_D3D9) | 
| -  D3DADAPTER_IDENTIFIER9 identifier; | 
| -  HRESULT hr = E_FAIL; | 
| -  HINSTANCE d3d_lib = LoadLibrary(L"d3d9.dll"); | 
| - | 
| -  if (d3d_lib) { | 
| -    typedef IDirect3D9* (WINAPI *D3DCreate9Proc)(UINT); | 
| -    D3DCreate9Proc d3d_create_proc = reinterpret_cast<D3DCreate9Proc>( | 
| -        GetProcAddress(d3d_lib, "Direct3DCreate9")); | 
| -    if (d3d_create_proc) { | 
| -      IDirect3D9* d3d = d3d_create_proc(D3D_SDK_VERSION); | 
| -      if (d3d) { | 
| -        hr = d3d->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &identifier); | 
| -        d3d->Release(); | 
| -      } | 
| -    } | 
| -    FreeLibrary(d3d_lib); | 
| -  } | 
| - | 
| -  if (hr != D3D_OK) { | 
| -    LOG(LS_ERROR) << "Failed to access Direct3D9 information."; | 
| -    return false; | 
| -  } | 
| - | 
| -  info->device_name = identifier.DeviceName; | 
| -  info->description = identifier.Description; | 
| -  info->vendor_id = identifier.VendorId; | 
| -  info->device_id = identifier.DeviceId; | 
| -  info->driver = identifier.Driver; | 
| -  // driver_version format: product.version.subversion.build | 
| -  std::stringstream ss; | 
| -  ss << HIWORD(identifier.DriverVersion.HighPart) << "." | 
| -     << LOWORD(identifier.DriverVersion.HighPart) << "." | 
| -     << HIWORD(identifier.DriverVersion.LowPart) << "." | 
| -     << LOWORD(identifier.DriverVersion.LowPart); | 
| -  info->driver_version = ss.str(); | 
| -  return true; | 
| -#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) | 
| -  // We'll query the IOKit for the gpu of the main display. | 
| -  io_service_t display_service_port = CGDisplayIOServicePort( | 
| -      kCGDirectMainDisplay); | 
| -  GetProperty(display_service_port, CFSTR("vendor-id"), &info->vendor_id); | 
| -  GetProperty(display_service_port, CFSTR("device-id"), &info->device_id); | 
| -  GetProperty(display_service_port, CFSTR("model"), &info->description); | 
| -  return true; | 
| -#else  // WEBRTC_LINUX | 
| -  // TODO(fbarchard): Implement this on Linux | 
| -  return false; | 
| -#endif | 
| -} | 
| }  // namespace rtc | 
|  |