OLD | NEW |
1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/gpu/gpu_info_collector.h" | 5 #include "chrome/gpu/gpu_info_collector.h" |
| 6 #include "base/sys_string_conversions.h" |
| 7 |
| 8 #import <Cocoa/Cocoa.h> |
| 9 #import <Foundation/Foundation.h> |
| 10 #import <IOKit/IOKitLib.h> |
| 11 #import <OpenGL/GL.h> |
6 | 12 |
7 namespace gpu_info_collector { | 13 namespace gpu_info_collector { |
8 | 14 |
| 15 static CFTypeRef SearchPortForProperty(io_registry_entry_t dspPort, |
| 16 CFStringRef propertyName) { |
| 17 return IORegistryEntrySearchCFProperty(dspPort, |
| 18 kIOServicePlane, |
| 19 propertyName, |
| 20 kCFAllocatorDefault, |
| 21 kIORegistryIterateRecursively | |
| 22 kIORegistryIterateParents); |
| 23 } |
| 24 |
| 25 static void CFReleaseIf(CFTypeRef type_ref) { |
| 26 if (type_ref) |
| 27 CFRelease(type_ref); |
| 28 } |
| 29 |
| 30 static UInt32 IntValueOfCFData(CFDataRef data_ref) { |
| 31 UInt32 value = 0; |
| 32 |
| 33 if (data_ref) { |
| 34 const UInt32 *value_pointer = |
| 35 reinterpret_cast<const UInt32*>(CFDataGetBytePtr(data_ref)); |
| 36 if (value_pointer != NULL) |
| 37 value = *value_pointer; |
| 38 } |
| 39 |
| 40 return value; |
| 41 } |
| 42 |
| 43 static void CollectVideoCardInfo(CGDirectDisplayID displayID, |
| 44 int *vendorID, |
| 45 int *deviceID) { |
| 46 io_registry_entry_t dspPort = CGDisplayIOServicePort(displayID); |
| 47 |
| 48 CFTypeRef vendorIDRef = SearchPortForProperty(dspPort, CFSTR("vendor-id")); |
| 49 if (vendorID) *vendorID = IntValueOfCFData((CFDataRef)vendorIDRef); |
| 50 |
| 51 CFTypeRef deviceIDRef = SearchPortForProperty(dspPort, CFSTR("device-id")); |
| 52 if (deviceID) *deviceID = IntValueOfCFData((CFDataRef)deviceIDRef); |
| 53 |
| 54 CFReleaseIf(vendorIDRef); |
| 55 CFReleaseIf(deviceIDRef); |
| 56 } |
| 57 |
| 58 // Return a pointer to the last character with value c in string s. |
| 59 // Returns NULL if c is not found. |
| 60 static char* FindLastChar(char *s, char c) { |
| 61 char *s_found = NULL; |
| 62 |
| 63 while (*s != '\0') { |
| 64 if (*s == c) |
| 65 s_found = s; |
| 66 s++; |
| 67 } |
| 68 return s_found; |
| 69 } |
| 70 |
| 71 |
9 bool CollectGraphicsInfo(GPUInfo& gpu_info) { | 72 bool CollectGraphicsInfo(GPUInfo& gpu_info) { |
10 // TODO(rlp): complete this function | 73 int vendor_id = 0; |
| 74 int device_id = 0; |
| 75 std::wstring driver_version = L""; |
| 76 uint32 pixel_shader_version = 0u; |
| 77 uint32 vertex_shader_version = 0u; |
| 78 uint32 gl_version; |
| 79 |
| 80 CollectVideoCardInfo(kCGDirectMainDisplay, &vendor_id, &device_id); |
| 81 |
| 82 char *gl_version_string = (char*)glGetString(GL_VERSION); |
| 83 char *gl_extensions_string = (char*)glGetString(GL_EXTENSIONS); |
| 84 |
| 85 if ((gl_version_string == NULL) || (gl_extensions_string == NULL)) |
| 86 return false; |
| 87 |
| 88 // Get the OpenGL version from the start of the string. |
| 89 int gl_major = 0, gl_minor = 0; |
| 90 sscanf(gl_version_string, "%u.%u", &gl_major, &gl_minor); |
| 91 |
| 92 // Get the OpenGL driver version. |
| 93 // Mac OpenGL drivers have the driver version |
| 94 // at the end of the gl version string preceded by a dash. |
| 95 char *s = FindLastChar(gl_version_string, '-'); |
| 96 if (s) { |
| 97 NSString *driver_version_ns = [[NSString alloc ] initWithUTF8String:s + 1]; |
| 98 driver_version = base::SysNSStringToWide(driver_version_ns); |
| 99 [driver_version_ns release]; |
| 100 } |
| 101 |
| 102 // Get the HLSL version. |
| 103 // On OpenGL 1.x it's 1.0 if the GL_ARB_shading_language_100 extension is |
| 104 // present. |
| 105 // On OpenGL 2.x it's a matter of getting the GL_SHADING_LANGUAGE_VERSION |
| 106 // string. |
| 107 int gl_hlsl_major = 0, gl_hlsl_minor = 0; |
| 108 if ((gl_major == 1) && |
| 109 strstr(gl_extensions_string, "GL_ARB_shading_language_100")) { |
| 110 gl_hlsl_major = 1; |
| 111 gl_hlsl_minor = 0; |
| 112 } else if (gl_major >= 2) { |
| 113 char* glsl_version_string = (char*)glGetString(GL_SHADING_LANGUAGE_VERSION); |
| 114 if (glsl_version_string) { |
| 115 sscanf(glsl_version_string, "%u.%u", &gl_hlsl_major, &gl_hlsl_minor); |
| 116 } |
| 117 } |
| 118 pixel_shader_version = ((gl_hlsl_major << 16) & 0xffff0000) |
| 119 + (gl_hlsl_minor & 0x0000ffff); |
| 120 |
| 121 // OpenGL doesn't have separate versions for pixel and vertex shader |
| 122 // languages, so set them both to the GL_SHADING_LANGUAGE_VERSION value. |
| 123 vertex_shader_version = pixel_shader_version; |
| 124 |
| 125 gl_version = ((gl_major << 16) & 0xffff0000) |
| 126 + (gl_minor & 0x0000ffff); |
| 127 |
| 128 gpu_info.SetGraphicsInfo(vendor_id, device_id, driver_version, |
| 129 pixel_shader_version, vertex_shader_version, |
| 130 gl_version); |
11 return true; | 131 return true; |
12 } | 132 } |
13 | 133 |
14 } // namespace gpu_info_collector | 134 } // namespace gpu_info_collector |
OLD | NEW |