Index: content/gpu/gpu_info_collector_win.cc |
diff --git a/content/gpu/gpu_info_collector_win.cc b/content/gpu/gpu_info_collector_win.cc |
index 1533a48291856969387b87418626ecf0a102b624..1e011df45f9e33e1ce9c6d99dd8538294df457fd 100644 |
--- a/content/gpu/gpu_info_collector_win.cc |
+++ b/content/gpu/gpu_info_collector_win.cc |
@@ -7,16 +7,17 @@ |
#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/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 "libxml/libxml_utils.h" |
#include "ui/gfx/gl/gl_implementation.h" |
#include "ui/gfx/gl/gl_surface_egl.h" |
@@ -35,66 +36,88 @@ 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"; |
- return stats; |
- } |
- |
- base::win::ScopedComPtr<IQueryRecentWinSATAssessment> assessment; |
- HRESULT hr = assessment.CreateInstance(__uuidof(CQueryWinSAT), NULL, |
- CLSCTX_INPROC_SERVER); |
- if (FAILED(hr)) { |
- LOG(ERROR) << "CoCreateInstance() failed"; |
+ // 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<IProvideWinSATResultsInfo> results; |
- hr = assessment->get_Info(results.Receive()); |
- if (FAILED(hr)) { |
- LOG(ERROR) << "get_Info() 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; |
} |
- WINSAT_ASSESSMENT_STATE state = WINSAT_ASSESSMENT_STATE_UNKNOWN; |
- hr = results->get_AssessmentState(&state); |
- if (FAILED(hr)) { |
- LOG(ERROR) << "get_AssessmentState() 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; |
} |
- if (state != WINSAT_ASSESSMENT_STATE_VALID && |
- state != WINSAT_ASSESSMENT_STATE_INCOHERENT_WITH_HARDWARE) { |
- LOG(ERROR) << "Can't retrieve a valid assessment"; |
- return stats; |
+ // Get relevant scores from results file. XML schema at: |
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/aa969210.aspx |
+ XmlReader reader; |
+ reader.LoadFile(current_results_string); |
+ reader.SkipToElement(); // Go to first XML tag. |
+ reader.Read(); // Descend into <WinSAT> root element. |
+ // Search for <WinSPR> element containing the results. |
+ do { |
+ if (reader.NodeName() == "WinSPR") |
+ break; |
+ } while (reader.Next()); |
+ reader.Read(); // Descend into <WinSPR> element. |
vangelis
2012/05/03 20:45:37
You should probably check here that you did indeed
dtu
2012/05/15 21:59:58
Done.
|
+ |
+ // 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); |
} |
- hr = results->get_SystemRating(&stats.overall); |
- if (FAILED(hr)) |
- LOG(ERROR) << "Get overall score failed"; |
- |
- stats.gaming = GetAssessmentScore(results, WINSAT_ASSESSMENT_D3D); |
- if (stats.gaming == 0.0) |
- LOG(ERROR) << "Get gaming score failed"; |
- |
- stats.graphics = GetAssessmentScore(results, WINSAT_ASSESSMENT_GRAPHICS); |
+ if (stats.overall == 0.0) |
+ LOG(ERROR) << "Could not read overall score from assessment results."; |
if (stats.graphics == 0.0) |
- LOG(ERROR) << "Get graphics score failed"; |
+ LOG(ERROR) << "Could not read graphics score from assessment results."; |
+ if (stats.gaming == 0.0) |
+ LOG(ERROR) << "Could not read gaming score from assessment results."; |
return stats; |
} |