| Index: chrome/gpu/gpu_info_collector_mac.mm
|
| ===================================================================
|
| --- chrome/gpu/gpu_info_collector_mac.mm (revision 56911)
|
| +++ chrome/gpu/gpu_info_collector_mac.mm (working copy)
|
| @@ -3,11 +3,131 @@
|
| // found in the LICENSE file.
|
|
|
| #include "chrome/gpu/gpu_info_collector.h"
|
| +#include "base/sys_string_conversions.h"
|
|
|
| +#import <Cocoa/Cocoa.h>
|
| +#import <Foundation/Foundation.h>
|
| +#import <IOKit/IOKitLib.h>
|
| +#import <OpenGL/GL.h>
|
| +
|
| namespace gpu_info_collector {
|
|
|
| +static CFTypeRef SearchPortForProperty(io_registry_entry_t dspPort,
|
| + CFStringRef propertyName) {
|
| + return IORegistryEntrySearchCFProperty(dspPort,
|
| + kIOServicePlane,
|
| + propertyName,
|
| + kCFAllocatorDefault,
|
| + kIORegistryIterateRecursively |
|
| + kIORegistryIterateParents);
|
| +}
|
| +
|
| +static void CFReleaseIf(CFTypeRef type_ref) {
|
| + if (type_ref)
|
| + CFRelease(type_ref);
|
| +}
|
| +
|
| +static UInt32 IntValueOfCFData(CFDataRef data_ref) {
|
| + UInt32 value = 0;
|
| +
|
| + if (data_ref) {
|
| + const UInt32 *value_pointer =
|
| + reinterpret_cast<const UInt32*>(CFDataGetBytePtr(data_ref));
|
| + if (value_pointer != NULL)
|
| + value = *value_pointer;
|
| + }
|
| +
|
| + return value;
|
| +}
|
| +
|
| +static void CollectVideoCardInfo(CGDirectDisplayID displayID,
|
| + int *vendorID,
|
| + int *deviceID) {
|
| + io_registry_entry_t dspPort = CGDisplayIOServicePort(displayID);
|
| +
|
| + CFTypeRef vendorIDRef = SearchPortForProperty(dspPort, CFSTR("vendor-id"));
|
| + if (vendorID) *vendorID = IntValueOfCFData((CFDataRef)vendorIDRef);
|
| +
|
| + CFTypeRef deviceIDRef = SearchPortForProperty(dspPort, CFSTR("device-id"));
|
| + if (deviceID) *deviceID = IntValueOfCFData((CFDataRef)deviceIDRef);
|
| +
|
| + CFReleaseIf(vendorIDRef);
|
| + CFReleaseIf(deviceIDRef);
|
| +}
|
| +
|
| +// Return a pointer to the last character with value c in string s.
|
| +// Returns NULL if c is not found.
|
| +static char* FindLastChar(char *s, char c) {
|
| + char *s_found = NULL;
|
| +
|
| + while (*s != '\0') {
|
| + if (*s == c)
|
| + s_found = s;
|
| + s++;
|
| + }
|
| + return s_found;
|
| +}
|
| +
|
| +
|
| bool CollectGraphicsInfo(GPUInfo& gpu_info) {
|
| - // TODO(rlp): complete this function
|
| + int vendor_id = 0;
|
| + int device_id = 0;
|
| + std::wstring driver_version = L"";
|
| + uint32 pixel_shader_version = 0u;
|
| + uint32 vertex_shader_version = 0u;
|
| + uint32 gl_version;
|
| +
|
| + CollectVideoCardInfo(kCGDirectMainDisplay, &vendor_id, &device_id);
|
| +
|
| + char *gl_version_string = (char*)glGetString(GL_VERSION);
|
| + char *gl_extensions_string = (char*)glGetString(GL_EXTENSIONS);
|
| +
|
| + if ((gl_version_string == NULL) || (gl_extensions_string == NULL))
|
| + return false;
|
| +
|
| + // Get the OpenGL version from the start of the string.
|
| + int gl_major = 0, gl_minor = 0;
|
| + sscanf(gl_version_string, "%u.%u", &gl_major, &gl_minor);
|
| +
|
| + // Get the OpenGL driver version.
|
| + // Mac OpenGL drivers have the driver version
|
| + // at the end of the gl version string preceded by a dash.
|
| + char *s = FindLastChar(gl_version_string, '-');
|
| + if (s) {
|
| + NSString *driver_version_ns = [[NSString alloc ] initWithUTF8String:s + 1];
|
| + driver_version = base::SysNSStringToWide(driver_version_ns);
|
| + [driver_version_ns release];
|
| + }
|
| +
|
| + // Get the HLSL version.
|
| + // On OpenGL 1.x it's 1.0 if the GL_ARB_shading_language_100 extension is
|
| + // present.
|
| + // On OpenGL 2.x it's a matter of getting the GL_SHADING_LANGUAGE_VERSION
|
| + // string.
|
| + int gl_hlsl_major = 0, gl_hlsl_minor = 0;
|
| + if ((gl_major == 1) &&
|
| + strstr(gl_extensions_string, "GL_ARB_shading_language_100")) {
|
| + gl_hlsl_major = 1;
|
| + gl_hlsl_minor = 0;
|
| + } else if (gl_major >= 2) {
|
| + char* glsl_version_string = (char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
|
| + if (glsl_version_string) {
|
| + sscanf(glsl_version_string, "%u.%u", &gl_hlsl_major, &gl_hlsl_minor);
|
| + }
|
| + }
|
| + pixel_shader_version = ((gl_hlsl_major << 16) & 0xffff0000)
|
| + + (gl_hlsl_minor & 0x0000ffff);
|
| +
|
| + // OpenGL doesn't have separate versions for pixel and vertex shader
|
| + // languages, so set them both to the GL_SHADING_LANGUAGE_VERSION value.
|
| + vertex_shader_version = pixel_shader_version;
|
| +
|
| + gl_version = ((gl_major << 16) & 0xffff0000)
|
| + + (gl_minor & 0x0000ffff);
|
| +
|
| + gpu_info.SetGraphicsInfo(vendor_id, device_id, driver_version,
|
| + pixel_shader_version, vertex_shader_version,
|
| + gl_version);
|
| return true;
|
| }
|
|
|
|
|