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

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

Issue 10128002: Retrieve Windows performance assessment information from results files. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge. Created 8 years, 7 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/DEPS ('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>
11 10
12 #include "base/command_line.h" 11 #include "base/command_line.h"
13 #include "base/file_path.h" 12 #include "base/file_path.h"
13 #include "base/file_util.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" 18 #include "base/win/scoped_com_initializer.h"
19 #include "base/win/scoped_comptr.h" 19 #include "base/win/scoped_comptr.h"
20 #include "third_party/libxml/chromium/libxml_utils.h"
20 #include "ui/gl/gl_implementation.h" 21 #include "ui/gl/gl_implementation.h"
21 #include "ui/gl/gl_surface_egl.h" 22 #include "ui/gl/gl_surface_egl.h"
22 23
23 // ANGLE seems to require that main.h be included before any other ANGLE header. 24 // ANGLE seems to require that main.h be included before any other ANGLE header.
24 #include "libEGL/Display.h" 25 #include "libEGL/Display.h"
25 #include "libEGL/main.h" 26 #include "libEGL/main.h"
26 27
27 namespace { 28 namespace {
28 29
29 // The version number stores the major and minor version in the least 16 bits; 30 // The version number stores the major and minor version in the least 16 bits;
30 // for example, 2.5 is 0x00000205. 31 // for example, 2.5 is 0x00000205.
31 // Returned string is in the format of "major.minor". 32 // Returned string is in the format of "major.minor".
32 std::string VersionNumberToString(uint32 version_number) { 33 std::string VersionNumberToString(uint32 version_number) {
33 int hi = (version_number >> 8) & 0xff; 34 int hi = (version_number >> 8) & 0xff;
34 int low = version_number & 0xff; 35 int low = version_number & 0xff;
35 return base::IntToString(hi) + "." + base::IntToString(low); 36 return base::IntToString(hi) + "." + base::IntToString(low);
36 } 37 }
37 38
38 float GetAssessmentScore(IProvideWinSATResultsInfo* results, 39 float ReadXMLFloatValue(XmlReader* reader) {
39 WINSAT_ASSESSMENT_TYPE type) { 40 std::string score_string;
40 base::win::ScopedComPtr<IProvideWinSATAssessmentInfo> subcomponent; 41 if (!reader->ReadElementContent(&score_string))
41 if (FAILED(results->GetAssessmentInfo(type, subcomponent.Receive())))
42 return 0.0; 42 return 0.0;
43 43
44 float score = 0.0; 44 double score;
45 if (FAILED(subcomponent->get_Score(&score))) 45 if (!base::StringToDouble(score_string, &score))
46 score = 0.0; 46 return 0.0;
47 return score; 47
48 return static_cast<float>(score);
48 } 49 }
49 50
50 content::GpuPerformanceStats RetrieveGpuPerformanceStats() { 51 content::GpuPerformanceStats RetrieveGpuPerformanceStats() {
52 // If the user re-runs the assessment without restarting, the COM API
53 // returns WINSAT_ASSESSMENT_STATE_NOT_AVAILABLE. Because of that and
54 // http://crbug.com/124325, read the assessment result files directly.
51 content::GpuPerformanceStats stats; 55 content::GpuPerformanceStats stats;
52 56
53 base::win::ScopedCOMInitializer com_initializer; 57 // Get path to WinSAT results files.
54 if (!com_initializer.succeeded()) { 58 wchar_t winsat_results_path[MAX_PATH];
55 LOG(ERROR) << "CoInitializeEx() failed"; 59 DWORD size = ExpandEnvironmentStrings(
60 L"%WinDir%\\Performance\\WinSAT\\DataStore\\",
61 winsat_results_path, MAX_PATH);
62 if (size == 0 || size > MAX_PATH) {
63 LOG(ERROR) << "The path to the WinSAT results is too long: "
64 << size << " chars.";
56 return stats; 65 return stats;
57 } 66 }
58 67
59 base::win::ScopedComPtr<IQueryRecentWinSATAssessment> assessment; 68 // Find most recent formal assessment results.
60 HRESULT hr = assessment.CreateInstance(__uuidof(CQueryWinSAT), NULL, 69 file_util::FileEnumerator file_enumerator(
61 CLSCTX_INPROC_SERVER); 70 FilePath(winsat_results_path),
62 if (FAILED(hr)) { 71 false, // not recursive
63 LOG(ERROR) << "CoCreateInstance() failed"; 72 file_util::FileEnumerator::FILES,
73 FILE_PATH_LITERAL("* * Formal.Assessment (*).WinSAT.xml"));
74
75 FilePath current_results;
76 for (FilePath results = file_enumerator.Next(); !results.empty();
77 results = file_enumerator.Next()) {
78 // The filenames start with the date and time as yyyy-mm-dd hh.mm.ss.xxx,
79 // so the greatest file lexicographically is also the most recent file.
80 if (FilePath::CompareLessIgnoreCase(current_results.value(),
81 results.value()))
82 current_results = results;
83 }
84
85 std::string current_results_string = current_results.MaybeAsASCII();
86 if (current_results_string.empty()) {
87 LOG(ERROR) << "Can't retrieve a valid WinSAT assessment.";
64 return stats; 88 return stats;
65 } 89 }
66 90
67 base::win::ScopedComPtr<IProvideWinSATResultsInfo> results; 91 // Get relevant scores from results file. XML schema at:
68 hr = assessment->get_Info(results.Receive()); 92 // http://msdn.microsoft.com/en-us/library/windows/desktop/aa969210.aspx
69 if (FAILED(hr)) { 93 XmlReader reader;
70 LOG(ERROR) << "get_Info() failed"; 94 if (!reader.LoadFile(current_results_string)) {
95 LOG(ERROR) << "Could not open WinSAT results file.";
96 return stats;
97 }
98 // Descend into <WinSAT> root element.
99 if (!reader.SkipToElement() || !reader.Read()) {
100 LOG(ERROR) << "Could not read WinSAT results file.";
71 return stats; 101 return stats;
72 } 102 }
73 103
74 WINSAT_ASSESSMENT_STATE state = WINSAT_ASSESSMENT_STATE_UNKNOWN; 104 // Search for <WinSPR> element containing the results.
75 hr = results->get_AssessmentState(&state); 105 do {
76 if (FAILED(hr)) { 106 if (reader.NodeName() == "WinSPR")
77 LOG(ERROR) << "get_AssessmentState() failed"; 107 break;
108 } while (reader.Next());
109 // Descend into <WinSPR> element.
110 if (!reader.Read()) {
111 LOG(ERROR) << "Could not find WinSPR element in results file.";
78 return stats; 112 return stats;
79 } 113 }
80 114
81 if (state != WINSAT_ASSESSMENT_STATE_VALID && 115 // Read scores.
82 state != WINSAT_ASSESSMENT_STATE_INCOHERENT_WITH_HARDWARE) { 116 for (int depth = reader.Depth(); reader.Depth() == depth; reader.Next()) {
83 LOG(ERROR) << "Can't retrieve a valid assessment"; 117 std::string node_name = reader.NodeName();
84 return stats; 118 if (node_name == "SystemScore")
119 stats.overall = ReadXMLFloatValue(&reader);
120 else if (node_name == "GraphicsScore")
121 stats.graphics = ReadXMLFloatValue(&reader);
122 else if (node_name == "GamingScore")
123 stats.gaming = ReadXMLFloatValue(&reader);
85 } 124 }
86 125
87 hr = results->get_SystemRating(&stats.overall); 126 if (stats.overall == 0.0)
88 if (FAILED(hr)) 127 LOG(ERROR) << "Could not read overall score from assessment results.";
89 LOG(ERROR) << "Get overall score failed"; 128 if (stats.graphics == 0.0)
90 129 LOG(ERROR) << "Could not read graphics score from assessment results.";
91 stats.gaming = GetAssessmentScore(results, WINSAT_ASSESSMENT_D3D);
92 if (stats.gaming == 0.0) 130 if (stats.gaming == 0.0)
93 LOG(ERROR) << "Get gaming score failed"; 131 LOG(ERROR) << "Could not read gaming score from assessment results.";
94
95 stats.graphics = GetAssessmentScore(results, WINSAT_ASSESSMENT_GRAPHICS);
96 if (stats.graphics == 0.0)
97 LOG(ERROR) << "Get graphics score failed";
98 132
99 return stats; 133 return stats;
100 } 134 }
101 135
102 } // namespace anonymous 136 } // namespace anonymous
103 137
104 namespace gpu_info_collector { 138 namespace gpu_info_collector {
105 139
106 bool CollectGraphicsInfo(content::GPUInfo* gpu_info) { 140 bool CollectGraphicsInfo(content::GPUInfo* gpu_info) {
107 DCHECK(gpu_info); 141 DCHECK(gpu_info);
108 142
109 gpu_info->performance_stats = RetrieveGpuPerformanceStats(); 143 gpu_info->performance_stats = RetrieveGpuPerformanceStats();
vangelis 2012/05/16 16:36:52 We should call this on windows only.
dtu 2012/05/16 18:46:57 Isn't this entire file Windows-only?
110 144
111 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL)) { 145 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL)) {
112 std::string requested_implementation_name = 146 std::string requested_implementation_name =
113 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kUseGL); 147 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kUseGL);
114 if (requested_implementation_name == "swiftshader") { 148 if (requested_implementation_name == "swiftshader") {
115 gpu_info->software_rendering = true; 149 gpu_info->software_rendering = true;
116 return false; 150 return false;
117 } 151 }
118 } 152 }
119 153
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 345
312 size_t pos = gl_version_string.find_last_not_of("0123456789."); 346 size_t pos = gl_version_string.find_last_not_of("0123456789.");
313 if (pos != std::string::npos && pos < gl_version_string.length() - 1) { 347 if (pos != std::string::npos && pos < gl_version_string.length() - 1) {
314 gpu_info->driver_version = gl_version_string.substr(pos + 1); 348 gpu_info->driver_version = gl_version_string.substr(pos + 1);
315 return true; 349 return true;
316 } 350 }
317 return false; 351 return false;
318 } 352 }
319 353
320 } // namespace gpu_info_collector 354 } // namespace gpu_info_collector
OLDNEW
« no previous file with comments | « content/gpu/DEPS ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698