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 |