| 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 9afef2380cd28563921db9c30e68ad5b9e6732a9..0b769d13d016c3b0eadc22835f0817846394392c 100644
|
| --- a/content/gpu/gpu_info_collector_linux.cc
|
| +++ b/content/gpu/gpu_info_collector_linux.cc
|
| @@ -8,6 +8,11 @@
|
| #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"
|
| @@ -28,51 +33,14 @@
|
|
|
| namespace {
|
|
|
| -// PciDevice and PciAccess are defined to access libpci functions. Their
|
| -// members match the corresponding structures defined by libpci in size up to
|
| -// fields we may access. For those members we don't use, their names are
|
| -// defined as "fieldX", etc., or, left out if they are declared after the
|
| -// members we care about in libpci.
|
| -
|
| -struct PciDevice {
|
| - PciDevice* next;
|
| -
|
| - uint16 field0;
|
| - uint8 field1;
|
| - uint8 field2;
|
| - uint8 field3;
|
| - int field4;
|
| -
|
| - uint16 vendor_id;
|
| - uint16 device_id;
|
| - uint16 device_class;
|
| -};
|
| -
|
| -struct PciAccess {
|
| - unsigned int field0;
|
| - int field1;
|
| - int field2;
|
| - char* field3;
|
| - int field4;
|
| - int field5;
|
| - unsigned int field6;
|
| - int field7;
|
| -
|
| - void (*function0)();
|
| - void (*function1)();
|
| - void (*function2)();
|
| -
|
| - PciDevice* device_list;
|
| -};
|
| -
|
| // Define function types.
|
| -typedef PciAccess* (*FT_pci_alloc)();
|
| -typedef void (*FT_pci_init)(PciAccess*);
|
| -typedef void (*FT_pci_cleanup)(PciAccess*);
|
| -typedef void (*FT_pci_scan_bus)(PciAccess*);
|
| -typedef void (*FT_pci_scan_bus)(PciAccess*);
|
| -typedef int (*FT_pci_fill_info)(PciDevice*, int);
|
| -typedef char* (*FT_pci_lookup_name)(PciAccess*, char*, int, int, ...);
|
| +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.
|
| @@ -100,12 +68,13 @@ bool IsPciSupported() {
|
| // 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;
|
| }
|
| - PciInterface* interface = new struct PciInterface;
|
| interface->lib_handle = handle;
|
| interface->pci_alloc = reinterpret_cast<FT_pci_alloc>(
|
| dlsym(handle, "pci_alloc"));
|
| @@ -127,16 +96,32 @@ PciInterface* InitializeLibPci(const char* lib_name) {
|
| interface->pci_lookup_name == NULL) {
|
| VLOG(1) << "Missing required function(s) from " << lib_name;
|
| dlclose(handle);
|
| - delete interface;
|
| return NULL;
|
| }
|
| - return interface;
|
| +#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;
|
| }
|
| @@ -281,12 +266,12 @@ bool CollectVideoCardInfo(content::GPUInfo* gpu_info) {
|
| return false;
|
| }
|
|
|
| - PciAccess* access = (interface->pci_alloc)();
|
| + pci_access* access = (interface->pci_alloc)();
|
| DCHECK(access != NULL);
|
| (interface->pci_init)(access);
|
| (interface->pci_scan_bus)(access);
|
| bool primary_gpu_identified = false;
|
| - for (PciDevice* device = access->device_list;
|
| + for (pci_dev* device = access->devices;
|
| device != NULL; device = device->next) {
|
| (interface->pci_fill_info)(device, 33); // Fill the IDs and class fields.
|
| // TODO(zmo): there might be other classes that qualify as display devices.
|
|
|