Chromium Code Reviews| 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; |
| } |