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

Side by Side Diff: content/gpu/gpu_info_collector_win.cc

Issue 10022011: Use Scoped COM helpers for collecting GPU information (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: License bump Created 8 years, 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/gpu/gpu_info_collector_unittest_win.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/gpu/gpu_info_collector.h" 5 #include "content/gpu/gpu_info_collector.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <d3d9.h> 8 #include <d3d9.h>
9 #include <setupapi.h> 9 #include <setupapi.h>
10 #include <winsatcominterfacei.h> 10 #include <winsatcominterfacei.h>
11 11
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/file_path.h" 13 #include "base/file_path.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/scoped_native_library.h" 15 #include "base/scoped_native_library.h"
16 #include "base/string_number_conversions.h" 16 #include "base/string_number_conversions.h"
17 #include "base/string_util.h" 17 #include "base/string_util.h"
18 #include "base/win/scoped_com_initializer.h"
19 #include "base/win/scoped_comptr.h"
18 #include "ui/gfx/gl/gl_implementation.h" 20 #include "ui/gfx/gl/gl_implementation.h"
19 #include "ui/gfx/gl/gl_surface_egl.h" 21 #include "ui/gfx/gl/gl_surface_egl.h"
20 22
21 // ANGLE seems to require that main.h be included before any other ANGLE header. 23 // ANGLE seems to require that main.h be included before any other ANGLE header.
22 #include "libEGL/Display.h" 24 #include "libEGL/Display.h"
23 #include "libEGL/main.h" 25 #include "libEGL/main.h"
24 26
25 namespace { 27 namespace {
26 28
27 // The version number stores the major and minor version in the least 16 bits; 29 // The version number stores the major and minor version in the least 16 bits;
28 // for example, 2.5 is 0x00000205. 30 // for example, 2.5 is 0x00000205.
29 // Returned string is in the format of "major.minor". 31 // Returned string is in the format of "major.minor".
30 std::string VersionNumberToString(uint32 version_number) { 32 std::string VersionNumberToString(uint32 version_number) {
31 int hi = (version_number >> 8) & 0xff; 33 int hi = (version_number >> 8) & 0xff;
32 int low = version_number & 0xff; 34 int low = version_number & 0xff;
33 return base::IntToString(hi) + "." + base::IntToString(low); 35 return base::IntToString(hi) + "." + base::IntToString(low);
34 } 36 }
35 37
36 float GetAssessmentScore(IProvideWinSATResultsInfo* results, 38 float GetAssessmentScore(IProvideWinSATResultsInfo* results,
37 WINSAT_ASSESSMENT_TYPE type) { 39 WINSAT_ASSESSMENT_TYPE type) {
38 IProvideWinSATAssessmentInfo* subcomponent = NULL; 40 base::win::ScopedComPtr<IProvideWinSATAssessmentInfo> subcomponent;
39 if (FAILED(results->GetAssessmentInfo(type, &subcomponent))) 41 if (FAILED(results->GetAssessmentInfo(type, subcomponent.Receive())))
40 return 0.0; 42 return 0.0;
41 43
42 float score = 0.0; 44 float score = 0.0;
43 if (FAILED(subcomponent->get_Score(&score))) 45 if (FAILED(subcomponent->get_Score(&score)))
44 score = 0.0; 46 score = 0.0;
45 subcomponent->Release();
46 return score; 47 return score;
47 } 48 }
48 49
49 content::GpuPerformanceStats RetrieveGpuPerformanceStats() { 50 content::GpuPerformanceStats RetrieveGpuPerformanceStats() {
50 IQueryRecentWinSATAssessment* assessment = NULL;
51 IProvideWinSATResultsInfo* results = NULL;
52
53 content::GpuPerformanceStats stats; 51 content::GpuPerformanceStats stats;
54 52
55 do { 53 base::win::ScopedCOMInitializer com_initializer;
56 HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); 54 if (!com_initializer.succeeded()) {
57 if (FAILED(hr)) { 55 LOG(ERROR) << "CoInitializeEx() failed";
58 LOG(ERROR) << "CoInitializeEx() failed"; 56 return stats;
59 break; 57 }
60 }
61 58
62 hr = CoCreateInstance(__uuidof(CQueryWinSAT), 59 base::win::ScopedComPtr<IQueryRecentWinSATAssessment> assessment;
63 NULL, 60 HRESULT hr = assessment.CreateInstance(__uuidof(CQueryWinSAT), NULL,
64 CLSCTX_INPROC_SERVER, 61 CLSCTX_INPROC_SERVER);
65 __uuidof(IQueryRecentWinSATAssessment), 62 if (FAILED(hr)) {
66 reinterpret_cast<void**>(&assessment)); 63 LOG(ERROR) << "CoCreateInstance() failed";
67 if (FAILED(hr)) { 64 return stats;
68 LOG(ERROR) << "CoCreateInstance() failed"; 65 }
69 break;
70 }
71 66
72 hr = assessment->get_Info(&results); 67 base::win::ScopedComPtr<IProvideWinSATResultsInfo> results;
73 if (FAILED(hr)) { 68 hr = assessment->get_Info(results.Receive());
74 LOG(ERROR) << "get_Info() failed"; 69 if (FAILED(hr)) {
75 break; 70 LOG(ERROR) << "get_Info() failed";
76 } 71 return stats;
72 }
77 73
78 WINSAT_ASSESSMENT_STATE state = WINSAT_ASSESSMENT_STATE_UNKNOWN; 74 WINSAT_ASSESSMENT_STATE state = WINSAT_ASSESSMENT_STATE_UNKNOWN;
79 hr = results->get_AssessmentState(&state); 75 hr = results->get_AssessmentState(&state);
80 if (FAILED(hr)) { 76 if (FAILED(hr)) {
81 LOG(ERROR) << "get_AssessmentState() failed"; 77 LOG(ERROR) << "get_AssessmentState() failed";
82 break; 78 return stats;
83 } 79 }
84 if (state != WINSAT_ASSESSMENT_STATE_VALID &&
85 state != WINSAT_ASSESSMENT_STATE_INCOHERENT_WITH_HARDWARE) {
86 LOG(ERROR) << "Can't retrieve a valid assessment";
87 break;
88 }
89 80
90 hr = results->get_SystemRating(&stats.overall); 81 if (state != WINSAT_ASSESSMENT_STATE_VALID &&
91 if (FAILED(hr)) 82 state != WINSAT_ASSESSMENT_STATE_INCOHERENT_WITH_HARDWARE) {
92 LOG(ERROR) << "Get overall score failed"; 83 LOG(ERROR) << "Can't retrieve a valid assessment";
84 return stats;
85 }
93 86
94 stats.gaming = GetAssessmentScore(results, WINSAT_ASSESSMENT_D3D); 87 hr = results->get_SystemRating(&stats.overall);
95 if (stats.gaming == 0.0) 88 if (FAILED(hr))
96 LOG(ERROR) << "Get gaming score failed"; 89 LOG(ERROR) << "Get overall score failed";
97 90
98 stats.graphics = GetAssessmentScore(results, WINSAT_ASSESSMENT_GRAPHICS); 91 stats.gaming = GetAssessmentScore(results, WINSAT_ASSESSMENT_D3D);
99 if (stats.graphics == 0.0) 92 if (stats.gaming == 0.0)
100 LOG(ERROR) << "Get graphics score failed"; 93 LOG(ERROR) << "Get gaming score failed";
101 } while (false);
102 94
103 if (assessment) 95 stats.graphics = GetAssessmentScore(results, WINSAT_ASSESSMENT_GRAPHICS);
104 assessment->Release(); 96 if (stats.graphics == 0.0)
105 if (results) 97 LOG(ERROR) << "Get graphics score failed";
106 results->Release();
107 CoUninitialize();
108 98
109 return stats; 99 return stats;
110 } 100 }
111 101
112 } // namespace anonymous 102 } // namespace anonymous
113 103
114 namespace gpu_info_collector { 104 namespace gpu_info_collector {
115 105
116 bool CollectGraphicsInfo(content::GPUInfo* gpu_info) { 106 bool CollectGraphicsInfo(content::GPUInfo* gpu_info) {
117 DCHECK(gpu_info); 107 DCHECK(gpu_info);
(...skipping 23 matching lines...) Expand all
141 LOG(ERROR) << "gfx::BaseEGLContext::GetDisplay() failed"; 131 LOG(ERROR) << "gfx::BaseEGLContext::GetDisplay() failed";
142 return false; 132 return false;
143 } 133 }
144 134
145 IDirect3DDevice9* device = display->getDevice(); 135 IDirect3DDevice9* device = display->getDevice();
146 if (!device) { 136 if (!device) {
147 LOG(ERROR) << "display->getDevice() failed"; 137 LOG(ERROR) << "display->getDevice() failed";
148 return false; 138 return false;
149 } 139 }
150 140
151 IDirect3D9* d3d = NULL; 141 base::win::ScopedComPtr<IDirect3D9> d3d;
152 if (FAILED(device->GetDirect3D(&d3d))) { 142 if (FAILED(device->GetDirect3D(d3d.Receive()))) {
153 LOG(ERROR) << "device->GetDirect3D(&d3d) failed"; 143 LOG(ERROR) << "device->GetDirect3D(&d3d) failed";
154 return false; 144 return false;
155 } 145 }
156 146
157 if (!CollectGraphicsInfoD3D(d3d, gpu_info)) 147 if (!CollectGraphicsInfoD3D(d3d, gpu_info))
158 return false; 148 return false;
159 149
160 // DirectX diagnostics are collected asynchronously because it takes a 150 // DirectX diagnostics are collected asynchronously because it takes a
161 // couple of seconds. Do not mark gpu_info as complete until that is done. 151 // couple of seconds. Do not mark gpu_info as complete until that is done.
162 return true; 152 return true;
(...skipping 25 matching lines...) Expand all
188 gpu_info->pixel_shader_version = 178 gpu_info->pixel_shader_version =
189 VersionNumberToString(d3d_caps.PixelShaderVersion); 179 VersionNumberToString(d3d_caps.PixelShaderVersion);
190 gpu_info->vertex_shader_version = 180 gpu_info->vertex_shader_version =
191 VersionNumberToString(d3d_caps.VertexShaderVersion); 181 VersionNumberToString(d3d_caps.VertexShaderVersion);
192 } else { 182 } else {
193 LOG(ERROR) << "d3d->GetDeviceCaps() failed"; 183 LOG(ERROR) << "d3d->GetDeviceCaps() failed";
194 succeed = false; 184 succeed = false;
195 } 185 }
196 186
197 // Get can_lose_context 187 // Get can_lose_context
198 bool can_lose_context = false; 188 base::win::ScopedComPtr<IDirect3D9Ex> d3dex;
199 IDirect3D9Ex* d3dex = NULL; 189 if (SUCCEEDED(d3dex.QueryFrom(d3d)))
200 if (SUCCEEDED(d3d->QueryInterface(__uuidof(IDirect3D9Ex), 190 gpu_info->can_lose_context = false;
201 reinterpret_cast<void**>(&d3dex)))) { 191 else
202 d3dex->Release(); 192 gpu_info->can_lose_context = true;
203 } else {
204 can_lose_context = true;
205 }
206 gpu_info->can_lose_context = can_lose_context;
207 193
208 d3d->Release();
209 return true; 194 return true;
210 } 195 }
211 196
212 bool CollectVideoCardInfo(content::GPUInfo* gpu_info) { 197 bool CollectVideoCardInfo(content::GPUInfo* gpu_info) {
213 DCHECK(gpu_info); 198 DCHECK(gpu_info);
214 199
215 // nvd3d9wrap.dll is loaded into all processes when Optimus is enabled. 200 // nvd3d9wrap.dll is loaded into all processes when Optimus is enabled.
216 HMODULE nvd3d9wrap = GetModuleHandleW(L"nvd3d9wrap.dll"); 201 HMODULE nvd3d9wrap = GetModuleHandleW(L"nvd3d9wrap.dll");
217 gpu_info->optimus = nvd3d9wrap != NULL; 202 gpu_info->optimus = nvd3d9wrap != NULL;
218 203
(...skipping 20 matching lines...) Expand all
239 // TODO(zmo): we only need to call CollectDriverInfoD3D() if we use ANGLE. 224 // TODO(zmo): we only need to call CollectDriverInfoD3D() if we use ANGLE.
240 return CollectDriverInfoD3D(id, gpu_info); 225 return CollectDriverInfoD3D(id, gpu_info);
241 } 226 }
242 return false; 227 return false;
243 } 228 }
244 229
245 bool CollectDriverInfoD3D(const std::wstring& device_id, 230 bool CollectDriverInfoD3D(const std::wstring& device_id,
246 content::GPUInfo* gpu_info) { 231 content::GPUInfo* gpu_info) {
247 // create device info for the display device 232 // create device info for the display device
248 HDEVINFO device_info = SetupDiGetClassDevsW( 233 HDEVINFO device_info = SetupDiGetClassDevsW(
249 NULL, device_id.c_str(), NULL, 234 NULL, device_id.c_str(), NULL,
250 DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES); 235 DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES);
251 if (device_info == INVALID_HANDLE_VALUE) { 236 if (device_info == INVALID_HANDLE_VALUE) {
252 LOG(ERROR) << "Creating device info failed"; 237 LOG(ERROR) << "Creating device info failed";
253 return false; 238 return false;
254 } 239 }
255 240
256 DWORD index = 0; 241 DWORD index = 0;
257 bool found = false; 242 bool found = false;
258 SP_DEVINFO_DATA device_info_data; 243 SP_DEVINFO_DATA device_info_data;
259 device_info_data.cbSize = sizeof(device_info_data); 244 device_info_data.cbSize = sizeof(device_info_data);
260 while (SetupDiEnumDeviceInfo(device_info, index++, &device_info_data)) { 245 while (SetupDiEnumDeviceInfo(device_info, index++, &device_info_data)) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 311
327 size_t pos = gl_version_string.find_last_not_of("0123456789."); 312 size_t pos = gl_version_string.find_last_not_of("0123456789.");
328 if (pos != std::string::npos && pos < gl_version_string.length() - 1) { 313 if (pos != std::string::npos && pos < gl_version_string.length() - 1) {
329 gpu_info->driver_version = gl_version_string.substr(pos + 1); 314 gpu_info->driver_version = gl_version_string.substr(pos + 1);
330 return true; 315 return true;
331 } 316 }
332 return false; 317 return false;
333 } 318 }
334 319
335 } // namespace gpu_info_collector 320 } // namespace gpu_info_collector
OLDNEW
« no previous file with comments | « content/gpu/gpu_info_collector_unittest_win.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698