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

Unified Diff: content/gpu/gpu_info_collector_mac.mm

Issue 10383146: Collect multiple GPUs' info on Mac and display them in about:gpu. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 7 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/common/gpu/gpu_messages.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/gpu/gpu_info_collector_mac.mm
===================================================================
--- content/gpu/gpu_info_collector_mac.mm (revision 137173)
+++ content/gpu/gpu_info_collector_mac.mm (working copy)
@@ -22,29 +22,23 @@
namespace {
-struct VideoCardInfo {
- UInt32 vendor_id;
- UInt32 device_id;
+const UInt32 kVendorIDIntel = 0x8086;
+const UInt32 kVendorIDNVidia = 0x10de;
+const UInt32 kVendorIDAMD = 0x1002;
- VideoCardInfo(UInt32 vendor, UInt32 device) {
- vendor_id = vendor;
- device_id = device;
- }
-};
+// Return 0 if we couldn't find the property.
+// The property values we use should not be 0, so it's OK to use 0 as failure.
+UInt32 GetEntryProperty(io_registry_entry_t entry, CFStringRef property_name) {
+ base::mac::ScopedCFTypeRef<CFDataRef> data_ref(static_cast<CFDataRef>(
+ IORegistryEntrySearchCFProperty(entry,
+ kIOServicePlane,
+ property_name,
+ kCFAllocatorDefault,
+ kIORegistryIterateRecursively |
+ kIORegistryIterateParents)));
+ if (!data_ref)
+ return 0;
-CFTypeRef SearchPortForProperty(io_registry_entry_t dspPort,
- CFStringRef propertyName) {
- return IORegistryEntrySearchCFProperty(dspPort,
- kIOServicePlane,
- propertyName,
- kCFAllocatorDefault,
- kIORegistryIterateRecursively |
- kIORegistryIterateParents);
-}
-
-UInt32 IntValueOfCFData(CFDataRef data_ref) {
- DCHECK(data_ref);
-
UInt32 value = 0;
const UInt32* value_pointer =
reinterpret_cast<const UInt32*>(CFDataGetBytePtr(data_ref));
@@ -53,69 +47,107 @@
return value;
}
+// Find the info of the current GPU.
+content::GPUInfo::GPUDevice GetActiveGPU() {
+ content::GPUInfo::GPUDevice gpu;
+ io_registry_entry_t dsp_port = CGDisplayIOServicePort(kCGDirectMainDisplay);
+ gpu.vendor_id = GetEntryProperty(dsp_port, CFSTR("vendor-id"));
+ gpu.device_id = GetEntryProperty(dsp_port, CFSTR("device-id"));
+ return gpu;
+}
+
// Scan IO registry for PCI video cards.
-// If two cards are located, assume the non-Intel card is the high-end
-// one that's going to be used by Chromium GPU process.
-// If more than two cards are located, return false. In such rare situation,
-// video card information should be collected through identifying the currently
-// in-use card as in CollectVideoCardInfo().
bool CollectPCIVideoCardInfo(content::GPUInfo* gpu_info) {
DCHECK(gpu_info);
+ // Collect all GPUs' info.
// match_dictionary will be consumed by IOServiceGetMatchingServices, no need
// to release it.
CFMutableDictionaryRef match_dictionary = IOServiceMatching("IOPCIDevice");
io_iterator_t entry_iterator;
+ std::vector<content::GPUInfo::GPUDevice> gpu_list;
if (IOServiceGetMatchingServices(kIOMasterPortDefault,
match_dictionary,
- &entry_iterator) != kIOReturnSuccess)
- return false;
-
- std::vector<VideoCardInfo> video_card_list;
- io_registry_entry_t entry;
- while ((entry = IOIteratorNext(entry_iterator))) {
- base::mac::ScopedCFTypeRef<CFDataRef> class_code_ref(static_cast<CFDataRef>(
- SearchPortForProperty(entry, CFSTR("class-code"))));
- if (!class_code_ref)
- continue;
- UInt32 class_code = IntValueOfCFData(class_code_ref);
- if (class_code != 0x30000) // DISPLAY_VGA
- continue;
- base::mac::ScopedCFTypeRef<CFDataRef> vendor_id_ref(static_cast<CFDataRef>(
- SearchPortForProperty(entry, CFSTR("vendor-id"))));
- if (!vendor_id_ref)
- continue;
- UInt32 vendor_id = IntValueOfCFData(vendor_id_ref);
- base::mac::ScopedCFTypeRef<CFDataRef> device_id_ref(static_cast<CFDataRef>(
- SearchPortForProperty(entry, CFSTR("device-id"))));
- if (!device_id_ref)
- continue;
- UInt32 device_id = IntValueOfCFData(device_id_ref);
- video_card_list.push_back(VideoCardInfo(vendor_id, device_id));
+ &entry_iterator) == kIOReturnSuccess) {
+ io_registry_entry_t entry;
+ while ((entry = IOIteratorNext(entry_iterator))) {
+ content::GPUInfo::GPUDevice gpu;
+ if (GetEntryProperty(entry, CFSTR("class-code")) != 0x30000) {
+ // 0x30000 : DISPLAY_VGA
+ continue;
+ }
+ gpu.vendor_id = GetEntryProperty(entry, CFSTR("vendor-id"));
+ gpu.device_id = GetEntryProperty(entry, CFSTR("device-id"));
+ if (gpu.vendor_id && gpu.device_id)
+ gpu_list.push_back(gpu);
+ }
+ IOObjectRelease(entry_iterator);
}
- IOObjectRelease(entry_iterator);
- const UInt32 kIntelVendorId = 0x8086;
- size_t found = video_card_list.size();
- switch (video_card_list.size()) {
+ switch (gpu_list.size()) {
+ case 0:
+ return false;
case 1:
- found = 0;
+ gpu_info->gpu = gpu_list[0];
break;
case 2:
- if (video_card_list[0].vendor_id == kIntelVendorId &&
- video_card_list[1].vendor_id != kIntelVendorId)
- found = 1;
- else if (video_card_list[0].vendor_id != kIntelVendorId &&
- video_card_list[1].vendor_id == kIntelVendorId)
- found = 0;
+ {
+ int integrated = -1;
+ int discrete = -1;
+ if (gpu_list[0].vendor_id == kVendorIDIntel)
+ integrated = 0;
+ else if (gpu_list[1].vendor_id == kVendorIDIntel)
+ integrated = 1;
+ if (integrated >= 0) {
+ switch (gpu_list[1 - integrated].vendor_id) {
+ case kVendorIDAMD:
+ gpu_info->amd_switchable = true;
+ discrete = 1 - integrated;
+ break;
+ case kVendorIDNVidia:
+ gpu_info->optimus = true;
+ discrete = 1 - integrated;
+ break;
+ default:
+ break;
+ }
+ }
+ if (integrated >= 0 && discrete >= 0) {
+ // We always put discrete GPU as primary for blacklisting purpose.
+ gpu_info->gpu = gpu_list[discrete];
+ gpu_info->secondary_gpus.push_back(gpu_list[integrated]);
+ break;
+ }
+ // If it's not optimus or amd_switchable, we put the current GPU as
+ // primary. Fall through to default.
+ }
+ default:
+ {
+ content::GPUInfo::GPUDevice active_gpu = GetActiveGPU();
+ size_t current = gpu_list.size();
+ if (active_gpu.vendor_id && active_gpu.device_id) {
+ for (size_t i = 0; i < gpu_list.size(); ++i) {
+ if (gpu_list[i].vendor_id == active_gpu.vendor_id &&
+ gpu_list[i].device_id == active_gpu.device_id) {
+ current = i;
+ break;
+ }
+ }
+ }
+ if (current == gpu_list.size()) {
+ // If we fail to identify the current GPU, select any one as primary.
+ current = 0;
+ }
+ for (size_t i = 0; i < gpu_list.size(); ++i) {
+ if (i == current)
+ gpu_info->gpu = gpu_list[i];
+ else
+ gpu_info->secondary_gpus.push_back(gpu_list[i]);
+ }
+ }
break;
}
- if (found < video_card_list.size()) {
- gpu_info->gpu.vendor_id = video_card_list[found].vendor_id;
- gpu_info->gpu.device_id = video_card_list[found].device_id;
- return true;
- }
- return false;
+ return (gpu_info->gpu.vendor_id && gpu_info->gpu.device_id);
}
} // namespace anonymous
@@ -134,32 +166,11 @@
bool CollectPreliminaryGraphicsInfo(content::GPUInfo* gpu_info) {
DCHECK(gpu_info);
- bool rt = true;
- if (!CollectPCIVideoCardInfo(gpu_info) && !CollectVideoCardInfo(gpu_info))
- rt = false;
-
- return rt;
+ return CollectPCIVideoCardInfo(gpu_info);
}
bool CollectVideoCardInfo(content::GPUInfo* gpu_info) {
- DCHECK(gpu_info);
-
- UInt32 vendor_id = 0, device_id = 0;
- io_registry_entry_t dsp_port = CGDisplayIOServicePort(kCGDirectMainDisplay);
- CFTypeRef vendor_id_ref = SearchPortForProperty(dsp_port, CFSTR("vendor-id"));
- if (vendor_id_ref) {
- vendor_id = IntValueOfCFData((CFDataRef)vendor_id_ref);
- CFRelease(vendor_id_ref);
- }
- CFTypeRef device_id_ref = SearchPortForProperty(dsp_port, CFSTR("device-id"));
- if (device_id_ref) {
- device_id = IntValueOfCFData((CFDataRef)device_id_ref);
- CFRelease(device_id_ref);
- }
-
- gpu_info->gpu.vendor_id = vendor_id;
- gpu_info->gpu.device_id = device_id;
- return true;
+ return CollectPreliminaryGraphicsInfo(gpu_info);
}
bool CollectDriverInfoGL(content::GPUInfo* gpu_info) {
« no previous file with comments | « content/common/gpu/gpu_messages.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698