| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "gpu/config/gpu_info_collector_linux.h" | 5 #include "gpu/config/gpu_info_collector_linux.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 } | 62 } |
| 63 } | 63 } |
| 64 } | 64 } |
| 65 return std::string(); | 65 return std::string(); |
| 66 } | 66 } |
| 67 | 67 |
| 68 const uint32 kVendorIDIntel = 0x8086; | 68 const uint32 kVendorIDIntel = 0x8086; |
| 69 const uint32 kVendorIDNVidia = 0x10de; | 69 const uint32 kVendorIDNVidia = 0x10de; |
| 70 const uint32 kVendorIDAMD = 0x1002; | 70 const uint32 kVendorIDAMD = 0x1002; |
| 71 | 71 |
| 72 bool CollectPCIVideoCardInfo(GPUInfo* gpu_info) { | 72 CollectInfoResult CollectPCIVideoCardInfo(GPUInfo* gpu_info) { |
| 73 DCHECK(gpu_info); | 73 DCHECK(gpu_info); |
| 74 | 74 |
| 75 if (IsPciSupported() == false) { | 75 if (IsPciSupported() == false) { |
| 76 VLOG(1) << "PCI bus scanning is not supported"; | 76 VLOG(1) << "PCI bus scanning is not supported"; |
| 77 return false; | 77 return kCollectInfoNonFatalFailure; |
| 78 } | 78 } |
| 79 | 79 |
| 80 // TODO(zmo): be more flexible about library name. | 80 // TODO(zmo): be more flexible about library name. |
| 81 LibPciLoader libpci_loader; | 81 LibPciLoader libpci_loader; |
| 82 if (!libpci_loader.Load("libpci.so.3") && | 82 if (!libpci_loader.Load("libpci.so.3") && |
| 83 !libpci_loader.Load("libpci.so")) { | 83 !libpci_loader.Load("libpci.so")) { |
| 84 VLOG(1) << "Failed to locate libpci"; | 84 VLOG(1) << "Failed to locate libpci"; |
| 85 return false; | 85 return kCollectInfoNonFatalFailure; |
| 86 } | 86 } |
| 87 | 87 |
| 88 pci_access* access = (libpci_loader.pci_alloc)(); | 88 pci_access* access = (libpci_loader.pci_alloc)(); |
| 89 DCHECK(access != NULL); | 89 DCHECK(access != NULL); |
| 90 (libpci_loader.pci_init)(access); | 90 (libpci_loader.pci_init)(access); |
| 91 (libpci_loader.pci_scan_bus)(access); | 91 (libpci_loader.pci_scan_bus)(access); |
| 92 bool primary_gpu_identified = false; | 92 bool primary_gpu_identified = false; |
| 93 for (pci_dev* device = access->devices; | 93 for (pci_dev* device = access->devices; |
| 94 device != NULL; device = device->next) { | 94 device != NULL; device = device->next) { |
| 95 // Fill the IDs and class fields. | 95 // Fill the IDs and class fields. |
| 96 (libpci_loader.pci_fill_info)(device, 33); | 96 (libpci_loader.pci_fill_info)(device, 33); |
| 97 bool is_gpu = false; | 97 bool is_gpu = false; |
| 98 switch (device->device_class) { | 98 switch (device->device_class) { |
| 99 case PCI_CLASS_DISPLAY_VGA: | 99 case PCI_CLASS_DISPLAY_VGA: |
| 100 case PCI_CLASS_DISPLAY_XGA: | 100 case PCI_CLASS_DISPLAY_XGA: |
| 101 case PCI_CLASS_DISPLAY_3D: | 101 case PCI_CLASS_DISPLAY_3D: |
| 102 is_gpu = true; | 102 is_gpu = true; |
| 103 break; | 103 break; |
| 104 case PCI_CLASS_DISPLAY_OTHER: | 104 case PCI_CLASS_DISPLAY_OTHER: |
| 105 default: | 105 default: |
| 106 break; | 106 break; |
| 107 } | 107 } |
| 108 if (!is_gpu) | 108 if (!is_gpu) |
| 109 continue; | 109 continue; |
| 110 if (device->vendor_id == 0 || device->device_id == 0) |
| 111 continue; |
| 110 | 112 |
| 111 GPUInfo::GPUDevice gpu; | 113 GPUInfo::GPUDevice gpu; |
| 112 gpu.vendor_id = device->vendor_id; | 114 gpu.vendor_id = device->vendor_id; |
| 113 gpu.device_id = device->device_id; | 115 gpu.device_id = device->device_id; |
| 114 | 116 |
| 115 if (!primary_gpu_identified) { | 117 if (!primary_gpu_identified) { |
| 116 primary_gpu_identified = true; | 118 primary_gpu_identified = true; |
| 117 gpu_info->gpu = gpu; | 119 gpu_info->gpu = gpu; |
| 118 } else { | 120 } else { |
| 119 // TODO(zmo): if there are multiple GPUs, we assume the non Intel | 121 // TODO(zmo): if there are multiple GPUs, we assume the non Intel |
| (...skipping 12 matching lines...) Expand all Loading... |
| 132 // Detect Optimus or AMD Switchable GPU. | 134 // Detect Optimus or AMD Switchable GPU. |
| 133 if (gpu_info->secondary_gpus.size() == 1 && | 135 if (gpu_info->secondary_gpus.size() == 1 && |
| 134 gpu_info->secondary_gpus[0].vendor_id == kVendorIDIntel) { | 136 gpu_info->secondary_gpus[0].vendor_id == kVendorIDIntel) { |
| 135 if (gpu_info->gpu.vendor_id == kVendorIDNVidia) | 137 if (gpu_info->gpu.vendor_id == kVendorIDNVidia) |
| 136 gpu_info->optimus = true; | 138 gpu_info->optimus = true; |
| 137 if (gpu_info->gpu.vendor_id == kVendorIDAMD) | 139 if (gpu_info->gpu.vendor_id == kVendorIDAMD) |
| 138 gpu_info->amd_switchable = true; | 140 gpu_info->amd_switchable = true; |
| 139 } | 141 } |
| 140 | 142 |
| 141 (libpci_loader.pci_cleanup)(access); | 143 (libpci_loader.pci_cleanup)(access); |
| 142 return (primary_gpu_identified); | 144 if (!primary_gpu_identified) |
| 145 return kCollectInfoNonFatalFailure; |
| 146 return kCollectInfoSuccess; |
| 143 } | 147 } |
| 144 | 148 |
| 145 } // namespace anonymous | 149 } // namespace anonymous |
| 146 | 150 |
| 147 CollectInfoResult CollectContextGraphicsInfo(GPUInfo* gpu_info) { | 151 CollectInfoResult CollectContextGraphicsInfo(GPUInfo* gpu_info) { |
| 148 DCHECK(gpu_info); | 152 DCHECK(gpu_info); |
| 149 | 153 |
| 150 TRACE_EVENT0("gpu", "gpu_info_collector::CollectGraphicsInfo"); | 154 TRACE_EVENT0("gpu", "gpu_info_collector::CollectGraphicsInfo"); |
| 151 | 155 |
| 152 if (CommandLine::ForCurrentProcess()->HasSwitch( | 156 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 153 switches::kGpuNoContextLost)) { | 157 switches::kGpuNoContextLost)) { |
| 154 gpu_info->can_lose_context = false; | 158 gpu_info->can_lose_context = false; |
| 155 } else { | 159 } else { |
| 156 #if defined(OS_CHROMEOS) | 160 #if defined(OS_CHROMEOS) |
| 157 gpu_info->can_lose_context = false; | 161 gpu_info->can_lose_context = false; |
| 158 #else | 162 #else |
| 159 // TODO(zmo): need to consider the case where we are running on top | 163 // TODO(zmo): need to consider the case where we are running on top |
| 160 // of desktop GL and GL_ARB_robustness extension is available. | 164 // of desktop GL and GL_ARB_robustness extension is available. |
| 161 gpu_info->can_lose_context = | 165 gpu_info->can_lose_context = |
| 162 (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2); | 166 (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2); |
| 163 #endif | 167 #endif |
| 164 } | 168 } |
| 165 | 169 |
| 166 CollectInfoResult result = CollectGraphicsInfoGL(gpu_info); | 170 CollectInfoResult result = CollectGraphicsInfoGL(gpu_info); |
| 167 gpu_info->finalized = true; | 171 gpu_info->context_info_state = result; |
| 168 return result; | 172 return result; |
| 169 } | 173 } |
| 170 | 174 |
| 171 GpuIDResult CollectGpuID(uint32* vendor_id, uint32* device_id) { | 175 CollectInfoResult CollectGpuID(uint32* vendor_id, uint32* device_id) { |
| 172 DCHECK(vendor_id && device_id); | 176 DCHECK(vendor_id && device_id); |
| 173 *vendor_id = 0; | 177 *vendor_id = 0; |
| 174 *device_id = 0; | 178 *device_id = 0; |
| 175 | 179 |
| 176 GPUInfo gpu_info; | 180 GPUInfo gpu_info; |
| 177 if (CollectPCIVideoCardInfo(&gpu_info)) { | 181 CollectInfoResult result = CollectPCIVideoCardInfo(&gpu_info); |
| 182 if (result == kCollectInfoSuccess) { |
| 178 *vendor_id = gpu_info.gpu.vendor_id; | 183 *vendor_id = gpu_info.gpu.vendor_id; |
| 179 *device_id = gpu_info.gpu.device_id; | 184 *device_id = gpu_info.gpu.device_id; |
| 180 if (*vendor_id != 0 && *device_id != 0) | |
| 181 return kGpuIDSuccess; | |
| 182 } | 185 } |
| 183 return kGpuIDFailure; | 186 return result; |
| 184 } | 187 } |
| 185 | 188 |
| 186 CollectInfoResult CollectBasicGraphicsInfo(GPUInfo* gpu_info) { | 189 CollectInfoResult CollectBasicGraphicsInfo(GPUInfo* gpu_info) { |
| 187 DCHECK(gpu_info); | 190 DCHECK(gpu_info); |
| 188 | 191 |
| 189 bool rt = CollectPCIVideoCardInfo(gpu_info); | 192 CollectInfoResult result = CollectPCIVideoCardInfo(gpu_info); |
| 190 | 193 |
| 191 std::string driver_version; | 194 std::string driver_version; |
| 192 switch (gpu_info->gpu.vendor_id) { | 195 switch (gpu_info->gpu.vendor_id) { |
| 193 case kVendorIDAMD: | 196 case kVendorIDAMD: |
| 194 driver_version = CollectDriverVersionATI(); | 197 driver_version = CollectDriverVersionATI(); |
| 195 if (!driver_version.empty()) { | 198 if (!driver_version.empty()) { |
| 196 gpu_info->driver_vendor = "ATI / AMD"; | 199 gpu_info->driver_vendor = "ATI / AMD"; |
| 197 gpu_info->driver_version = driver_version; | 200 gpu_info->driver_version = driver_version; |
| 198 } | 201 } |
| 199 break; | 202 break; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 216 // Put Intel to the secondary GPU list. | 219 // Put Intel to the secondary GPU list. |
| 217 gpu_info->secondary_gpus.push_back(gpu_info->gpu); | 220 gpu_info->secondary_gpus.push_back(gpu_info->gpu); |
| 218 // Put NVIDIA as the primary GPU. | 221 // Put NVIDIA as the primary GPU. |
| 219 gpu_info->gpu.vendor_id = kVendorIDNVidia; | 222 gpu_info->gpu.vendor_id = kVendorIDNVidia; |
| 220 gpu_info->gpu.device_id = 0; // Unknown Device. | 223 gpu_info->gpu.device_id = 0; // Unknown Device. |
| 221 } | 224 } |
| 222 } | 225 } |
| 223 break; | 226 break; |
| 224 } | 227 } |
| 225 | 228 |
| 226 return rt ? kCollectInfoSuccess : kCollectInfoNonFatalFailure; | 229 gpu_info->basic_info_state = result; |
| 230 return result; |
| 227 } | 231 } |
| 228 | 232 |
| 229 CollectInfoResult CollectDriverInfoGL(GPUInfo* gpu_info) { | 233 CollectInfoResult CollectDriverInfoGL(GPUInfo* gpu_info) { |
| 230 DCHECK(gpu_info); | 234 DCHECK(gpu_info); |
| 231 | 235 |
| 232 std::string gl_version = gpu_info->gl_version; | 236 std::string gl_version = gpu_info->gl_version; |
| 233 if (StartsWithASCII(gl_version, "OpenGL ES", true)) | 237 if (StartsWithASCII(gl_version, "OpenGL ES", true)) |
| 234 gl_version = gl_version.substr(10); | 238 gl_version = gl_version.substr(10); |
| 235 std::vector<std::string> pieces; | 239 std::vector<std::string> pieces; |
| 236 base::SplitStringAlongWhitespace(gl_version, &pieces); | 240 base::SplitStringAlongWhitespace(gl_version, &pieces); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 250 gpu_info->driver_version = driver_version; | 254 gpu_info->driver_version = driver_version; |
| 251 return kCollectInfoSuccess; | 255 return kCollectInfoSuccess; |
| 252 } | 256 } |
| 253 | 257 |
| 254 void MergeGPUInfo(GPUInfo* basic_gpu_info, | 258 void MergeGPUInfo(GPUInfo* basic_gpu_info, |
| 255 const GPUInfo& context_gpu_info) { | 259 const GPUInfo& context_gpu_info) { |
| 256 MergeGPUInfoGL(basic_gpu_info, context_gpu_info); | 260 MergeGPUInfoGL(basic_gpu_info, context_gpu_info); |
| 257 } | 261 } |
| 258 | 262 |
| 259 } // namespace gpu | 263 } // namespace gpu |
| OLD | NEW |