summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordtu@chromium.org <dtu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-16 23:24:15 +0000
committerdtu@chromium.org <dtu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-16 23:24:15 +0000
commitb882891c004caaf6d50d0217aa690682f4b7ccd1 (patch)
tree7aac2166bfebb000bdfa2fa68cc4edabfa15168d
parent78bffa2e0c91305e1b9b89a8d9ba8f2e53cf245e (diff)
downloadchromium_src-b882891c004caaf6d50d0217aa690682f4b7ccd1.zip
chromium_src-b882891c004caaf6d50d0217aa690682f4b7ccd1.tar.gz
chromium_src-b882891c004caaf6d50d0217aa690682f4b7ccd1.tar.bz2
Retrieve Windows performance assessment information from results files.
Also move libxml_utils from chrome/common/ into base/, because it's now being used to read the results files from content/gpu/ TBR=ben@chromium.org BUG=chromium:122838,chromium:124325 TEST=Builds on all platforms, and chrome://gpu gives a correct rating after the user re-runs the WinSAT assessment. Review URL: https://chromiumcodereview.appspot.com/10128002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@137552 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/content_gpu.gypi1
-rw-r--r--content/gpu/DEPS1
-rw-r--r--content/gpu/gpu_info_collector_win.cc127
3 files changed, 91 insertions, 38 deletions
diff --git a/content/content_gpu.gypi b/content/content_gpu.gypi
index cda9ae0..b98d991 100644
--- a/content/content_gpu.gypi
+++ b/content/content_gpu.gypi
@@ -38,6 +38,7 @@
'dependencies': [
'../third_party/angle/src/build_angle.gyp:libEGL',
'../third_party/angle/src/build_angle.gyp:libGLESv2',
+ '../third_party/libxml/libxml.gyp:libxml',
],
'link_settings': {
'libraries': [
diff --git a/content/gpu/DEPS b/content/gpu/DEPS
index 082ffad..46de806 100644
--- a/content/gpu/DEPS
+++ b/content/gpu/DEPS
@@ -6,4 +6,5 @@ include_rules = [
"+libGLESv2",
"+sandbox",
"+skia",
+ "+third_party/libxml", # For parsing WinSAT results files.
]
diff --git a/content/gpu/gpu_info_collector_win.cc b/content/gpu/gpu_info_collector_win.cc
index d17e0ef..e37d0e9 100644
--- a/content/gpu/gpu_info_collector_win.cc
+++ b/content/gpu/gpu_info_collector_win.cc
@@ -7,16 +7,18 @@
#include <windows.h>
#include <d3d9.h>
#include <setupapi.h>
-#include <winsatcominterfacei.h>
#include "base/command_line.h"
#include "base/file_path.h"
+#include "base/file_util.h"
#include "base/logging.h"
+#include "base/metrics/histogram.h"
#include "base/scoped_native_library.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/win/scoped_com_initializer.h"
#include "base/win/scoped_comptr.h"
+#include "third_party/libxml/chromium/libxml_utils.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_surface_egl.h"
@@ -35,66 +37,111 @@ std::string VersionNumberToString(uint32 version_number) {
return base::IntToString(hi) + "." + base::IntToString(low);
}
-float GetAssessmentScore(IProvideWinSATResultsInfo* results,
- WINSAT_ASSESSMENT_TYPE type) {
- base::win::ScopedComPtr<IProvideWinSATAssessmentInfo> subcomponent;
- if (FAILED(results->GetAssessmentInfo(type, subcomponent.Receive())))
+float ReadXMLFloatValue(XmlReader* reader) {
+ std::string score_string;
+ if (!reader->ReadElementContent(&score_string))
return 0.0;
- float score = 0.0;
- if (FAILED(subcomponent->get_Score(&score)))
- score = 0.0;
- return score;
+ double score;
+ if (!base::StringToDouble(score_string, &score))
+ return 0.0;
+
+ return static_cast<float>(score);
}
content::GpuPerformanceStats RetrieveGpuPerformanceStats() {
+ // If the user re-runs the assessment without restarting, the COM API
+ // returns WINSAT_ASSESSMENT_STATE_NOT_AVAILABLE. Because of that and
+ // http://crbug.com/124325, read the assessment result files directly.
content::GpuPerformanceStats stats;
- base::win::ScopedCOMInitializer com_initializer;
- if (!com_initializer.succeeded()) {
- LOG(ERROR) << "CoInitializeEx() failed";
+ base::TimeTicks start_time = base::TimeTicks::Now();
+
+ // Get path to WinSAT results files.
+ wchar_t winsat_results_path[MAX_PATH];
+ DWORD size = ExpandEnvironmentStrings(
+ L"%WinDir%\\Performance\\WinSAT\\DataStore\\",
+ winsat_results_path, MAX_PATH);
+ if (size == 0 || size > MAX_PATH) {
+ LOG(ERROR) << "The path to the WinSAT results is too long: "
+ << size << " chars.";
return stats;
}
- base::win::ScopedComPtr<IQueryRecentWinSATAssessment> assessment;
- HRESULT hr = assessment.CreateInstance(__uuidof(CQueryWinSAT), NULL,
- CLSCTX_INPROC_SERVER);
- if (FAILED(hr)) {
- LOG(ERROR) << "CoCreateInstance() failed";
- return stats;
+ // Find most recent formal assessment results.
+ file_util::FileEnumerator file_enumerator(
+ FilePath(winsat_results_path),
+ false, // not recursive
+ file_util::FileEnumerator::FILES,
+ FILE_PATH_LITERAL("* * Formal.Assessment (*).WinSAT.xml"));
+
+ FilePath current_results;
+ for (FilePath results = file_enumerator.Next(); !results.empty();
+ results = file_enumerator.Next()) {
+ // The filenames start with the date and time as yyyy-mm-dd hh.mm.ss.xxx,
+ // so the greatest file lexicographically is also the most recent file.
+ if (FilePath::CompareLessIgnoreCase(current_results.value(),
+ results.value()))
+ current_results = results;
}
- base::win::ScopedComPtr<IProvideWinSATResultsInfo> results;
- hr = assessment->get_Info(results.Receive());
- if (FAILED(hr)) {
- LOG(ERROR) << "get_Info() failed";
+ std::string current_results_string = current_results.MaybeAsASCII();
+ if (current_results_string.empty()) {
+ LOG(ERROR) << "Can't retrieve a valid WinSAT assessment.";
return stats;
}
- WINSAT_ASSESSMENT_STATE state = WINSAT_ASSESSMENT_STATE_UNKNOWN;
- hr = results->get_AssessmentState(&state);
- if (FAILED(hr)) {
- LOG(ERROR) << "get_AssessmentState() failed";
+ // Get relevant scores from results file. XML schema at:
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/aa969210.aspx
+ XmlReader reader;
+ if (!reader.LoadFile(current_results_string)) {
+ LOG(ERROR) << "Could not open WinSAT results file.";
+ return stats;
+ }
+ // Descend into <WinSAT> root element.
+ if (!reader.SkipToElement() || !reader.Read()) {
+ LOG(ERROR) << "Could not read WinSAT results file.";
return stats;
}
- if (state != WINSAT_ASSESSMENT_STATE_VALID &&
- state != WINSAT_ASSESSMENT_STATE_INCOHERENT_WITH_HARDWARE) {
- LOG(ERROR) << "Can't retrieve a valid assessment";
+ // Search for <WinSPR> element containing the results.
+ do {
+ if (reader.NodeName() == "WinSPR")
+ break;
+ } while (reader.Next());
+ // Descend into <WinSPR> element.
+ if (!reader.Read()) {
+ LOG(ERROR) << "Could not find WinSPR element in results file.";
return stats;
}
- hr = results->get_SystemRating(&stats.overall);
- if (FAILED(hr))
- LOG(ERROR) << "Get overall score failed";
+ // Read scores.
+ for (int depth = reader.Depth(); reader.Depth() == depth; reader.Next()) {
+ std::string node_name = reader.NodeName();
+ if (node_name == "SystemScore")
+ stats.overall = ReadXMLFloatValue(&reader);
+ else if (node_name == "GraphicsScore")
+ stats.graphics = ReadXMLFloatValue(&reader);
+ else if (node_name == "GamingScore")
+ stats.gaming = ReadXMLFloatValue(&reader);
+ }
- stats.gaming = GetAssessmentScore(results, WINSAT_ASSESSMENT_D3D);
+ if (stats.overall == 0.0)
+ LOG(ERROR) << "Could not read overall score from assessment results.";
+ if (stats.graphics == 0.0)
+ LOG(ERROR) << "Could not read graphics score from assessment results.";
if (stats.gaming == 0.0)
- LOG(ERROR) << "Get gaming score failed";
+ LOG(ERROR) << "Could not read gaming score from assessment results.";
- stats.graphics = GetAssessmentScore(results, WINSAT_ASSESSMENT_GRAPHICS);
- if (stats.graphics == 0.0)
- LOG(ERROR) << "Get graphics score failed";
+ UMA_HISTOGRAM_CUSTOM_COUNTS("GPU.WinSAT.OverallScore",
+ stats.overall, 0.0, 50.0, 50);
+ UMA_HISTOGRAM_CUSTOM_COUNTS("GPU.WinSAT.GraphicsScore",
+ stats.graphics, 0.0, 50.0, 50);
+ UMA_HISTOGRAM_CUSTOM_COUNTS("GPU.WinSAT.GamingScore",
+ stats.gaming, 0.0, 50.0, 50);
+
+ UMA_HISTOGRAM_TIMES("GPU.WinSAT.ReadResultsFileTime",
+ base::TimeTicks::Now() - start_time);
return stats;
}
@@ -106,7 +153,11 @@ namespace gpu_info_collector {
bool CollectGraphicsInfo(content::GPUInfo* gpu_info) {
DCHECK(gpu_info);
- gpu_info->performance_stats = RetrieveGpuPerformanceStats();
+ content::GpuPerformanceStats stats = RetrieveGpuPerformanceStats();
+ UMA_HISTOGRAM_BOOLEAN(
+ "GPU.WinSAT.HasResults",
+ stats.overall != 0.0 && stats.graphics != 0.0 && stats.gaming != 0.0);
+ gpu_info->performance_stats = stats;
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL)) {
std::string requested_implementation_name =