Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: content/gpu/gpu_info_collector_linux.cc

Issue 11343015: Linux: add option to link libpci directly instead of using dlopen. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: install-build-deps.sh Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« content/content_gpu.gypi ('K') | « content/content_gpu.gypi ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/gpu/gpu_info_collector.h" 5 #include "content/gpu/gpu_info_collector.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 #include <X11/Xlib.h> 8 #include <X11/Xlib.h>
9 #include <vector> 9 #include <vector>
10 10
11 // TODO(phajdan.jr): Report problem upstream and make pci.h handle this.
12 extern "C" {
13 #include <pci/pci.h>
piman 2012/10/29 17:24:24 This won't work correctly if you didn't have the p
14 }
15
11 #include "base/command_line.h" 16 #include "base/command_line.h"
12 #include "base/debug/trace_event.h" 17 #include "base/debug/trace_event.h"
13 #include "base/file_util.h" 18 #include "base/file_util.h"
14 #include "base/logging.h" 19 #include "base/logging.h"
15 #include "base/memory/scoped_ptr.h" 20 #include "base/memory/scoped_ptr.h"
16 #include "base/message_loop.h" 21 #include "base/message_loop.h"
17 #include "base/string_piece.h" 22 #include "base/string_piece.h"
18 #include "base/string_split.h" 23 #include "base/string_split.h"
19 #include "base/string_tokenizer.h" 24 #include "base/string_tokenizer.h"
20 #include "base/string_util.h" 25 #include "base/string_util.h"
21 #include "third_party/libXNVCtrl/NVCtrl.h" 26 #include "third_party/libXNVCtrl/NVCtrl.h"
22 #include "third_party/libXNVCtrl/NVCtrlLib.h" 27 #include "third_party/libXNVCtrl/NVCtrlLib.h"
23 #include "ui/gl/gl_bindings.h" 28 #include "ui/gl/gl_bindings.h"
24 #include "ui/gl/gl_context.h" 29 #include "ui/gl/gl_context.h"
25 #include "ui/gl/gl_implementation.h" 30 #include "ui/gl/gl_implementation.h"
26 #include "ui/gl/gl_surface.h" 31 #include "ui/gl/gl_surface.h"
27 #include "ui/gl/gl_switches.h" 32 #include "ui/gl/gl_switches.h"
28 33
29 namespace { 34 namespace {
30 35
31 // PciDevice and PciAccess are defined to access libpci functions. Their
32 // members match the corresponding structures defined by libpci in size up to
33 // fields we may access. For those members we don't use, their names are
34 // defined as "fieldX", etc., or, left out if they are declared after the
35 // members we care about in libpci.
36
37 struct PciDevice {
38 PciDevice* next;
39
40 uint16 field0;
41 uint8 field1;
42 uint8 field2;
43 uint8 field3;
44 int field4;
45
46 uint16 vendor_id;
47 uint16 device_id;
48 uint16 device_class;
49 };
50
51 struct PciAccess {
52 unsigned int field0;
53 int field1;
54 int field2;
55 char* field3;
56 int field4;
57 int field5;
58 unsigned int field6;
59 int field7;
60
61 void (*function0)();
62 void (*function1)();
63 void (*function2)();
64
65 PciDevice* device_list;
66 };
67
68 // Define function types. 36 // Define function types.
69 typedef PciAccess* (*FT_pci_alloc)(); 37 typedef pci_access* (*FT_pci_alloc)();
70 typedef void (*FT_pci_init)(PciAccess*); 38 typedef void (*FT_pci_init)(pci_access*);
71 typedef void (*FT_pci_cleanup)(PciAccess*); 39 typedef void (*FT_pci_cleanup)(pci_access*);
72 typedef void (*FT_pci_scan_bus)(PciAccess*); 40 typedef void (*FT_pci_scan_bus)(pci_access*);
73 typedef void (*FT_pci_scan_bus)(PciAccess*); 41 typedef void (*FT_pci_scan_bus)(pci_access*);
74 typedef int (*FT_pci_fill_info)(PciDevice*, int); 42 typedef int (*FT_pci_fill_info)(pci_dev*, int);
75 typedef char* (*FT_pci_lookup_name)(PciAccess*, char*, int, int, ...); 43 typedef char* (*FT_pci_lookup_name)(pci_access*, char*, int, int, ...);
76 44
77 // This includes dynamically linked library handle and functions pointers from 45 // This includes dynamically linked library handle and functions pointers from
78 // libpci. 46 // libpci.
79 struct PciInterface { 47 struct PciInterface {
80 void* lib_handle; 48 void* lib_handle;
81 49
82 FT_pci_alloc pci_alloc; 50 FT_pci_alloc pci_alloc;
83 FT_pci_init pci_init; 51 FT_pci_init pci_init;
84 FT_pci_cleanup pci_cleanup; 52 FT_pci_cleanup pci_cleanup;
85 FT_pci_scan_bus pci_scan_bus; 53 FT_pci_scan_bus pci_scan_bus;
86 FT_pci_fill_info pci_fill_info; 54 FT_pci_fill_info pci_fill_info;
87 FT_pci_lookup_name pci_lookup_name; 55 FT_pci_lookup_name pci_lookup_name;
88 }; 56 };
89 57
90 // This checks if a system supports PCI bus. 58 // This checks if a system supports PCI bus.
91 // We check the existence of /sys/bus/pci or /sys/bug/pci_express. 59 // We check the existence of /sys/bus/pci or /sys/bug/pci_express.
92 bool IsPciSupported() { 60 bool IsPciSupported() {
93 const FilePath pci_path("/sys/bus/pci/"); 61 const FilePath pci_path("/sys/bus/pci/");
94 const FilePath pcie_path("/sys/bus/pci_express/"); 62 const FilePath pcie_path("/sys/bus/pci_express/");
95 return (file_util::PathExists(pci_path) || 63 return (file_util::PathExists(pci_path) ||
96 file_util::PathExists(pcie_path)); 64 file_util::PathExists(pcie_path));
97 } 65 }
98 66
99 // This dynamically opens libpci and get function pointers we need. Return 67 // This dynamically opens libpci and get function pointers we need. Return
100 // NULL if library fails to open or any functions can not be located. 68 // NULL if library fails to open or any functions can not be located.
101 // Returned interface (if not NULL) should be deleted in FinalizeLibPci. 69 // Returned interface (if not NULL) should be deleted in FinalizeLibPci.
102 PciInterface* InitializeLibPci(const char* lib_name) { 70 PciInterface* InitializeLibPci(const char* lib_name) {
71 #if defined(DLOPEN_LIBPCI)
103 void* handle = dlopen(lib_name, RTLD_LAZY); 72 void* handle = dlopen(lib_name, RTLD_LAZY);
104 if (handle == NULL) { 73 if (handle == NULL) {
105 VLOG(1) << "Failed to dlopen " << lib_name; 74 VLOG(1) << "Failed to dlopen " << lib_name;
106 return NULL; 75 return NULL;
107 } 76 }
108 PciInterface* interface = new struct PciInterface; 77 PciInterface* interface = new struct PciInterface;
109 interface->lib_handle = handle; 78 interface->lib_handle = handle;
110 interface->pci_alloc = reinterpret_cast<FT_pci_alloc>( 79 interface->pci_alloc = reinterpret_cast<FT_pci_alloc>(
111 dlsym(handle, "pci_alloc")); 80 dlsym(handle, "pci_alloc"));
112 interface->pci_init = reinterpret_cast<FT_pci_init>( 81 interface->pci_init = reinterpret_cast<FT_pci_init>(
(...skipping 10 matching lines...) Expand all
123 interface->pci_init == NULL || 92 interface->pci_init == NULL ||
124 interface->pci_cleanup == NULL || 93 interface->pci_cleanup == NULL ||
125 interface->pci_scan_bus == NULL || 94 interface->pci_scan_bus == NULL ||
126 interface->pci_fill_info == NULL || 95 interface->pci_fill_info == NULL ||
127 interface->pci_lookup_name == NULL) { 96 interface->pci_lookup_name == NULL) {
128 VLOG(1) << "Missing required function(s) from " << lib_name; 97 VLOG(1) << "Missing required function(s) from " << lib_name;
129 dlclose(handle); 98 dlclose(handle);
130 delete interface; 99 delete interface;
131 return NULL; 100 return NULL;
132 } 101 }
102 #else // !defined(DLOPEN_LIBPCI)
103 PciInterface* interface = new struct PciInterface;
104 interface->lib_handle = NULL;
105 interface->pci_alloc = reinterpret_cast<FT_pci_alloc>(
piman 2012/10/29 17:24:24 Why do we need reinterpret_cast here?
106 &pci_alloc);
107 interface->pci_init = reinterpret_cast<FT_pci_init>(
108 &pci_init);
109 interface->pci_cleanup = reinterpret_cast<FT_pci_cleanup>(
110 &pci_cleanup);
111 interface->pci_scan_bus = reinterpret_cast<FT_pci_scan_bus>(
112 &pci_scan_bus);
113 interface->pci_fill_info = reinterpret_cast<FT_pci_fill_info>(
114 &pci_fill_info);
115 interface->pci_lookup_name = reinterpret_cast<FT_pci_lookup_name>(
116 &pci_lookup_name);
117 #endif // !defined(DLOPEN_LIBPCI)
133 return interface; 118 return interface;
134 } 119 }
135 120
136 // This close the dynamically opened libpci and delete the interface. 121 // This close the dynamically opened libpci and delete the interface.
137 void FinalizeLibPci(PciInterface** interface) { 122 void FinalizeLibPci(PciInterface** interface) {
123 #if defined(DLOPEN_LIBPCI)
138 DCHECK(interface && *interface && (*interface)->lib_handle); 124 DCHECK(interface && *interface && (*interface)->lib_handle);
139 dlclose((*interface)->lib_handle); 125 dlclose((*interface)->lib_handle);
126 #endif // defined(DLOPEN_LIBPCI)
140 delete (*interface); 127 delete (*interface);
141 *interface = NULL; 128 *interface = NULL;
142 } 129 }
143 130
144 // Scan /etc/ati/amdpcsdb.default for "ReleaseVersion". 131 // Scan /etc/ati/amdpcsdb.default for "ReleaseVersion".
145 // Return empty string on failing. 132 // Return empty string on failing.
146 std::string CollectDriverVersionATI() { 133 std::string CollectDriverVersionATI() {
147 const FilePath::CharType kATIFileName[] = 134 const FilePath::CharType kATIFileName[] =
148 FILE_PATH_LITERAL("/etc/ati/amdpcsdb.default"); 135 FILE_PATH_LITERAL("/etc/ati/amdpcsdb.default");
149 FilePath ati_file_path(kATIFileName); 136 FilePath ati_file_path(kATIFileName);
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 261
275 // TODO(zmo): be more flexible about library name. 262 // TODO(zmo): be more flexible about library name.
276 PciInterface* interface = InitializeLibPci("libpci.so.3"); 263 PciInterface* interface = InitializeLibPci("libpci.so.3");
277 if (interface == NULL) 264 if (interface == NULL)
278 interface = InitializeLibPci("libpci.so"); 265 interface = InitializeLibPci("libpci.so");
279 if (interface == NULL) { 266 if (interface == NULL) {
280 VLOG(1) << "Failed to locate libpci"; 267 VLOG(1) << "Failed to locate libpci";
281 return false; 268 return false;
282 } 269 }
283 270
284 PciAccess* access = (interface->pci_alloc)(); 271 pci_access* access = (interface->pci_alloc)();
285 DCHECK(access != NULL); 272 DCHECK(access != NULL);
286 (interface->pci_init)(access); 273 (interface->pci_init)(access);
287 (interface->pci_scan_bus)(access); 274 (interface->pci_scan_bus)(access);
288 bool primary_gpu_identified = false; 275 bool primary_gpu_identified = false;
289 for (PciDevice* device = access->device_list; 276 for (pci_dev* device = access->devices;
290 device != NULL; device = device->next) { 277 device != NULL; device = device->next) {
291 (interface->pci_fill_info)(device, 33); // Fill the IDs and class fields. 278 (interface->pci_fill_info)(device, 33); // Fill the IDs and class fields.
292 // TODO(zmo): there might be other classes that qualify as display devices. 279 // TODO(zmo): there might be other classes that qualify as display devices.
293 if (device->device_class != 0x0300) // Device class is DISPLAY_VGA. 280 if (device->device_class != 0x0300) // Device class is DISPLAY_VGA.
294 continue; 281 continue;
295 282
296 content::GPUInfo::GPUDevice gpu; 283 content::GPUInfo::GPUDevice gpu;
297 gpu.vendor_id = device->vendor_id; 284 gpu.vendor_id = device->vendor_id;
298 gpu.device_id = device->device_id; 285 gpu.device_id = device->device_id;
299 286
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 return false; 362 return false;
376 if (pos != std::string::npos) 363 if (pos != std::string::npos)
377 driver_version = driver_version.substr(0, pos); 364 driver_version = driver_version.substr(0, pos);
378 365
379 gpu_info->driver_vendor = pieces[1]; 366 gpu_info->driver_vendor = pieces[1];
380 gpu_info->driver_version = driver_version; 367 gpu_info->driver_version = driver_version;
381 return true; 368 return true;
382 } 369 }
383 370
384 } // namespace gpu_info_collector 371 } // namespace gpu_info_collector
OLDNEW
« content/content_gpu.gypi ('K') | « content/content_gpu.gypi ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698