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) { |