Index: content/gpu/gpu_info_collector_linux.cc |
diff --git a/content/gpu/gpu_info_collector_linux.cc b/content/gpu/gpu_info_collector_linux.cc |
index c6f2c2bcd7a97e32db76975f388cf934b819ebd5..d849cab7f25b6873d3cf512a9037aed056856fdf 100644 |
--- a/content/gpu/gpu_info_collector_linux.cc |
+++ b/content/gpu/gpu_info_collector_linux.cc |
@@ -4,15 +4,9 @@ |
#include "content/gpu/gpu_info_collector.h" |
-#include <dlfcn.h> |
#include <X11/Xlib.h> |
#include <vector> |
-// TODO(phajdan.jr): Report problem upstream and make pci.h handle this. |
-extern "C" { |
-#include <pci/pci.h> |
-} |
- |
#include "base/command_line.h" |
#include "base/debug/trace_event.h" |
#include "base/file_util.h" |
@@ -23,6 +17,7 @@ extern "C" { |
#include "base/string_split.h" |
#include "base/string_tokenizer.h" |
#include "base/string_util.h" |
+#include "library_loaders/libpci.h" |
#include "third_party/libXNVCtrl/NVCtrl.h" |
#include "third_party/libXNVCtrl/NVCtrlLib.h" |
#include "ui/gl/gl_bindings.h" |
@@ -33,28 +28,6 @@ extern "C" { |
namespace { |
-// Define function types. |
-typedef pci_access* (*FT_pci_alloc)(); |
-typedef void (*FT_pci_init)(pci_access*); |
-typedef void (*FT_pci_cleanup)(pci_access*); |
-typedef void (*FT_pci_scan_bus)(pci_access*); |
-typedef void (*FT_pci_scan_bus)(pci_access*); |
-typedef int (*FT_pci_fill_info)(pci_dev*, int); |
-typedef char* (*FT_pci_lookup_name)(pci_access*, char*, int, int, ...); |
- |
-// This includes dynamically linked library handle and functions pointers from |
-// libpci. |
-struct PciInterface { |
- void* lib_handle; |
- |
- FT_pci_alloc pci_alloc; |
- FT_pci_init pci_init; |
- FT_pci_cleanup pci_cleanup; |
- FT_pci_scan_bus pci_scan_bus; |
- FT_pci_fill_info pci_fill_info; |
- FT_pci_lookup_name pci_lookup_name; |
-}; |
- |
// This checks if a system supports PCI bus. |
// We check the existence of /sys/bus/pci or /sys/bug/pci_express. |
bool IsPciSupported() { |
@@ -64,68 +37,6 @@ bool IsPciSupported() { |
file_util::PathExists(pcie_path)); |
} |
-// This dynamically opens libpci and get function pointers we need. Return |
-// NULL if library fails to open or any functions can not be located. |
-// Returned interface (if not NULL) should be deleted in FinalizeLibPci. |
-PciInterface* InitializeLibPci(const char* lib_name) { |
- scoped_ptr<PciInterface> interface(new PciInterface); |
-#if defined(DLOPEN_LIBPCI) |
- void* handle = dlopen(lib_name, RTLD_LAZY); |
- if (handle == NULL) { |
- VLOG(1) << "Failed to dlopen " << lib_name; |
- return NULL; |
- } |
- interface->lib_handle = handle; |
- interface->pci_alloc = reinterpret_cast<FT_pci_alloc>( |
- dlsym(handle, "pci_alloc")); |
- interface->pci_init = reinterpret_cast<FT_pci_init>( |
- dlsym(handle, "pci_init")); |
- interface->pci_cleanup = reinterpret_cast<FT_pci_cleanup>( |
- dlsym(handle, "pci_cleanup")); |
- interface->pci_scan_bus = reinterpret_cast<FT_pci_scan_bus>( |
- dlsym(handle, "pci_scan_bus")); |
- interface->pci_fill_info = reinterpret_cast<FT_pci_fill_info>( |
- dlsym(handle, "pci_fill_info")); |
- interface->pci_lookup_name = reinterpret_cast<FT_pci_lookup_name>( |
- dlsym(handle, "pci_lookup_name")); |
- if (interface->pci_alloc == NULL || |
- interface->pci_init == NULL || |
- interface->pci_cleanup == NULL || |
- interface->pci_scan_bus == NULL || |
- interface->pci_fill_info == NULL || |
- interface->pci_lookup_name == NULL) { |
- VLOG(1) << "Missing required function(s) from " << lib_name; |
- dlclose(handle); |
- return NULL; |
- } |
-#else // !defined(DLOPEN_LIBPCI) |
- interface->lib_handle = NULL; |
- interface->pci_alloc = reinterpret_cast<FT_pci_alloc>( |
- &pci_alloc); |
- interface->pci_init = reinterpret_cast<FT_pci_init>( |
- &pci_init); |
- interface->pci_cleanup = reinterpret_cast<FT_pci_cleanup>( |
- &pci_cleanup); |
- interface->pci_scan_bus = reinterpret_cast<FT_pci_scan_bus>( |
- &pci_scan_bus); |
- interface->pci_fill_info = reinterpret_cast<FT_pci_fill_info>( |
- &pci_fill_info); |
- interface->pci_lookup_name = reinterpret_cast<FT_pci_lookup_name>( |
- &pci_lookup_name); |
-#endif // !defined(DLOPEN_LIBPCI) |
- return interface.release(); |
-} |
- |
-// This close the dynamically opened libpci and delete the interface. |
-void FinalizeLibPci(PciInterface** interface) { |
-#if defined(DLOPEN_LIBPCI) |
- DCHECK(interface && *interface && (*interface)->lib_handle); |
- dlclose((*interface)->lib_handle); |
-#endif // defined(DLOPEN_LIBPCI) |
- delete (*interface); |
- *interface = NULL; |
-} |
- |
// Scan /etc/ati/amdpcsdb.default for "ReleaseVersion". |
// Return empty string on failing. |
std::string CollectDriverVersionATI() { |
@@ -263,22 +174,22 @@ bool CollectVideoCardInfo(content::GPUInfo* gpu_info) { |
} |
// TODO(zmo): be more flexible about library name. |
- PciInterface* interface = InitializeLibPci("libpci.so.3"); |
- if (interface == NULL) |
- interface = InitializeLibPci("libpci.so"); |
- if (interface == NULL) { |
+ LibPciLoader libpci_loader; |
+ if (!libpci_loader.Load("libpci.so.3") && |
+ !libpci_loader.Load("libpci.so")) { |
VLOG(1) << "Failed to locate libpci"; |
return false; |
} |
- pci_access* access = (interface->pci_alloc)(); |
+ pci_access* access = (libpci_loader.pci_alloc)(); |
DCHECK(access != NULL); |
- (interface->pci_init)(access); |
- (interface->pci_scan_bus)(access); |
+ (libpci_loader.pci_init)(access); |
+ (libpci_loader.pci_scan_bus)(access); |
bool primary_gpu_identified = false; |
for (pci_dev* device = access->devices; |
device != NULL; device = device->next) { |
- (interface->pci_fill_info)(device, 33); // Fill the IDs and class fields. |
+ // Fill the IDs and class fields. |
+ (libpci_loader.pci_fill_info)(device, 33); |
// TODO(zmo): there might be other classes that qualify as display devices. |
if (device->device_class != 0x0300) // Device class is DISPLAY_VGA. |
continue; |
@@ -292,19 +203,19 @@ bool CollectVideoCardInfo(content::GPUInfo* gpu_info) { |
// The current implementation of pci_lookup_name returns the same pointer |
// as the passed in upon success, and a different one (NULL or a pointer |
// to an error message) upon failure. |
- if ((interface->pci_lookup_name)(access, |
- buffer.get(), |
- buffer_size, |
- 1, |
- device->vendor_id) == buffer.get()) { |
+ if ((libpci_loader.pci_lookup_name)(access, |
+ buffer.get(), |
+ buffer_size, |
+ 1, |
+ device->vendor_id) == buffer.get()) { |
gpu.vendor_string = buffer.get(); |
} |
- if ((interface->pci_lookup_name)(access, |
- buffer.get(), |
- buffer_size, |
- 2, |
- device->vendor_id, |
- device->device_id) == buffer.get()) { |
+ if ((libpci_loader.pci_lookup_name)(access, |
+ buffer.get(), |
+ buffer_size, |
+ 2, |
+ device->vendor_id, |
+ device->device_id) == buffer.get()) { |
std::string device_string = buffer.get(); |
size_t begin = device_string.find_first_of('['); |
size_t end = device_string.find_last_of(']'); |
@@ -341,8 +252,7 @@ bool CollectVideoCardInfo(content::GPUInfo* gpu_info) { |
gpu_info->amd_switchable = true; |
} |
- (interface->pci_cleanup)(access); |
- FinalizeLibPci(&interface); |
+ (libpci_loader.pci_cleanup)(access); |
return (primary_gpu_identified); |
} |