Chromium Code Reviews| Index: content/gpu/gpu_info_collector_mac.mm |
| =================================================================== |
| --- content/gpu/gpu_info_collector_mac.mm (revision 136605) |
| +++ content/gpu/gpu_info_collector_mac.mm (working copy) |
| @@ -22,16 +22,9 @@ |
| namespace { |
| -struct VideoCardInfo { |
| - UInt32 vendor_id; |
| - UInt32 device_id; |
| +const UInt32 kVendorIDIntel = 0x8086; |
| +const UInt32 kVendorIDAMD = 0x1002; |
| - VideoCardInfo(UInt32 vendor, UInt32 device) { |
| - vendor_id = vendor; |
| - device_id = device; |
| - } |
| -}; |
| - |
| CFTypeRef SearchPortForProperty(io_registry_entry_t dspPort, |
| CFStringRef propertyName) { |
| return IORegistryEntrySearchCFProperty(dspPort, |
| @@ -54,68 +47,75 @@ |
| } |
| // 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 the active GPU's info. |
| + io_registry_entry_t dsp_port = CGDisplayIOServicePort(kCGDirectMainDisplay); |
| + CFTypeRef vendor_id_ref = SearchPortForProperty(dsp_port, CFSTR("vendor-id")); |
| + if (vendor_id_ref) { |
| + gpu_info->gpu.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) { |
| + gpu_info->gpu.device_id = IntValueOfCFData((CFDataRef)device_id_ref); |
| + CFRelease(device_id_ref); |
| + } |
| + |
| + // 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; |
| 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))) { |
|
Ken Russell (switch to Gerrit)
2012/05/11 22:46:15
Because of the asymmetry between GPUInfo::gpu and
Zhenyao Mo
2012/05/14 18:41:11
Done.
|
| + content::GPUInfo::GPUDevice gpu; |
| + base::mac::ScopedCFTypeRef<CFDataRef> class_code_ref( |
| + static_cast<CFDataRef>(SearchPortForProperty(entry, |
| + CFSTR("class-code")))); |
|
Ken Russell (switch to Gerrit)
2012/05/11 22:46:15
There's a lot of boilerplate code duplicated in th
Zhenyao Mo
2012/05/14 18:41:11
Done.
|
| + 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; |
| + gpu.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; |
| + gpu.device_id = IntValueOfCFData(device_id_ref); |
| + if (gpu.vendor_id != gpu_info->gpu.vendor_id || |
| + gpu.device_id != gpu_info->gpu.device_id) |
| + gpu_info->secondary_gpus.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()) { |
| - case 1: |
| - found = 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; |
| - break; |
| + if (gpu_info->secondary_gpus.size() == 1) { |
| + if ((gpu_info->gpu.vendor_id == kVendorIDAMD && |
| + gpu_info->secondary_gpus[0].vendor_id == kVendorIDIntel) || |
| + (gpu_info->gpu.vendor_id == kVendorIDIntel && |
| + gpu_info->secondary_gpus[0].vendor_id == kVendorIDAMD)) { |
|
Ken Russell (switch to Gerrit)
2012/05/11 22:46:15
This must be generalized for non-AMD GPUs, or blac
Zhenyao Mo
2012/05/14 18:41:11
Is optimus supported on Mac also? Anyway, I imple
Ken Russell (switch to Gerrit)
2012/05/15 18:08:22
I believe that Apple implements their own GPU-swit
|
| + gpu_info->amd_switchable = true; |
| + if (gpu_info->gpu.vendor_id == kVendorIDIntel) { |
| + // We need to put AMD as primary for blacklist purpose. |
| + content::GPUInfo::GPUDevice gpu = gpu_info->gpu; |
| + gpu_info->gpu = gpu_info->secondary_gpus[0]; |
| + gpu_info->secondary_gpus[0] = gpu; |
| + } |
| + } |
| } |
| - 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 +134,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) { |