Commit 7004d7eb authored by zmo@google.com's avatar zmo@google.com

Refactor and improve gpu_info_collector: collect information on linux;

collect extra information (driver_vendor, gl_renderer, etc.) on Mac/linux.
Note that this CL takes some code from rlp's long outstandingCL (with her
permission).

BUG=49579
TEST=unittest

Review URL: http://codereview.chromium.org/6346007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@72055 0039d316-1c4b-4281-b951-d872f2087c98
parent c7a827e9
...@@ -280,7 +280,7 @@ DictionaryValue* GpuInfoToDict(const GPUInfo& gpu_info) { ...@@ -280,7 +280,7 @@ DictionaryValue* GpuInfoToDict(const GPUInfo& gpu_info) {
basic_info->Append(NewDescriptionValuePair("Device Id", basic_info->Append(NewDescriptionValuePair("Device Id",
base::StringPrintf("0x%04x", gpu_info.device_id()))); base::StringPrintf("0x%04x", gpu_info.device_id())));
basic_info->Append(NewDescriptionValuePair("Driver version", basic_info->Append(NewDescriptionValuePair("Driver version",
WideToASCII(gpu_info.driver_version()).c_str())); gpu_info.driver_version()));
basic_info->Append(NewDescriptionValuePair("Pixel shader version", basic_info->Append(NewDescriptionValuePair("Pixel shader version",
VersionNumberToString(gpu_info.pixel_shader_version()))); VersionNumberToString(gpu_info.pixel_shader_version())));
basic_info->Append(NewDescriptionValuePair("Vertex shader version", basic_info->Append(NewDescriptionValuePair("Vertex shader version",
......
...@@ -370,7 +370,7 @@ GpuFeatureFlags GpuBlacklist::DetermineGpuFeatureFlags( ...@@ -370,7 +370,7 @@ GpuFeatureFlags GpuBlacklist::DetermineGpuFeatureFlags(
if (gpu_info.progress() == GPUInfo::kUninitialized) if (gpu_info.progress() == GPUInfo::kUninitialized)
return flags; return flags;
scoped_ptr<Version> driver_version( scoped_ptr<Version> driver_version(
Version::GetVersionFromString(WideToASCII(gpu_info.driver_version()))); Version::GetVersionFromString(gpu_info.driver_version()));
if (driver_version.get() == NULL) if (driver_version.get() == NULL)
return flags; return flags;
...@@ -391,6 +391,9 @@ GpuFeatureFlags GpuBlacklist::DetermineGpuFeatureFlags( ...@@ -391,6 +391,9 @@ GpuFeatureFlags GpuBlacklist::DetermineGpuFeatureFlags(
version_bugfix); version_bugfix);
#else #else
version_string = base::SysInfo::OperatingSystemVersion(); version_string = base::SysInfo::OperatingSystemVersion();
size_t pos = version_string.find_first_not_of("0123456789.");
if (pos != std::string::npos)
version_string = version_string.substr(0, pos);
#endif #endif
my_os_version.reset(Version::GetVersionFromString(version_string)); my_os_version.reset(Version::GetVersionFromString(version_string));
os_version = my_os_version.get(); os_version = my_os_version.get();
......
...@@ -9,13 +9,10 @@ ...@@ -9,13 +9,10 @@
TEST(GpuBlacklistTest, BlacklistLogic) { TEST(GpuBlacklistTest, BlacklistLogic) {
GPUInfo gpu_info; GPUInfo gpu_info;
gpu_info.SetGraphicsInfo(0x10de, // Vendor ID gpu_info.SetVideoCardInfo(0x10de, // Vendor ID
0x0640, // Device ID 0x0640); // Device ID
L"1.6.18", // Driver Version gpu_info.SetDriverInfo("NVIDIA", // Driver vendor
0x0114, // Pixel Shader Version "1.6.18"); // Driver Version
0x0114, // Vertex Shader Version
0x0201, // GL version,
true); // can_lose_context
gpu_info.SetProgress(GPUInfo::kComplete); gpu_info.SetProgress(GPUInfo::kComplete);
scoped_ptr<Version> os_version(Version::GetVersionFromString("10.6.4")); scoped_ptr<Version> os_version(Version::GetVersionFromString("10.6.4"));
......
...@@ -675,6 +675,7 @@ ...@@ -675,6 +675,7 @@
'gpu/gpu_info_collector_linux.cc', 'gpu/gpu_info_collector_linux.cc',
'gpu/gpu_info_collector_mac.mm', 'gpu/gpu_info_collector_mac.mm',
'gpu/gpu_info_collector_win.cc', 'gpu/gpu_info_collector_win.cc',
'gpu/gpu_info_collector.cc',
'gpu/gpu_info_collector.h', 'gpu/gpu_info_collector.h',
'gpu/gpu_main.cc', 'gpu/gpu_main.cc',
'gpu/gpu_process.cc', 'gpu/gpu_process.cc',
......
...@@ -985,6 +985,7 @@ ...@@ -985,6 +985,7 @@
'utility', 'utility',
'../app/app.gyp:app_base', '../app/app.gyp:app_base',
'../app/app.gyp:app_resources', '../app/app.gyp:app_resources',
'../gpu/gpu.gyp:gpu_unittest_utils',
'../ipc/ipc.gyp:ipc', '../ipc/ipc.gyp:ipc',
'../media/media.gyp:media_test_support', '../media/media.gyp:media_test_support',
'../net/net.gyp:net_resources', '../net/net.gyp:net_resources',
...@@ -1671,6 +1672,7 @@ ...@@ -1671,6 +1672,7 @@
'common/worker_thread_ticker_unittest.cc', 'common/worker_thread_ticker_unittest.cc',
'common/zip_unittest.cc', 'common/zip_unittest.cc',
'gpu/gpu_idirect3d9_mock_win.h', 'gpu/gpu_idirect3d9_mock_win.h',
'gpu/gpu_info_collector_unittest.cc',
'gpu/gpu_info_unittest_win.cc', 'gpu/gpu_info_unittest_win.cc',
'gpu/gpu_video_decoder_unittest.cc', 'gpu/gpu_video_decoder_unittest.cc',
'renderer/audio_message_filter_unittest.cc', 'renderer/audio_message_filter_unittest.cc',
......
...@@ -151,7 +151,7 @@ void SetGpuInfoImpl(const GPUInfo& gpu_info, ...@@ -151,7 +151,7 @@ void SetGpuInfoImpl(const GPUInfo& gpu_info,
base::UintToString(gpu_info.device_id()), base::UintToString(gpu_info.device_id()),
set_key_func); set_key_func);
SetGpuKeyValue(kGPUDriverVersionParamName, SetGpuKeyValue(kGPUDriverVersionParamName,
WideToUTF8(gpu_info.driver_version()), gpu_info.driver_version(),
set_key_func); set_key_func);
SetGpuKeyValue(kGPUPixelShaderVersionParamName, SetGpuKeyValue(kGPUPixelShaderVersionParamName,
base::UintToString(gpu_info.pixel_shader_version()), base::UintToString(gpu_info.pixel_shader_version()),
......
...@@ -139,7 +139,7 @@ void SetGpuInfo(const GPUInfo& gpu_info) { ...@@ -139,7 +139,7 @@ void SetGpuInfo(const GPUInfo& gpu_info) {
(set_gpu_info)( (set_gpu_info)(
base::UintToString16(gpu_info.vendor_id()).c_str(), base::UintToString16(gpu_info.vendor_id()).c_str(),
base::UintToString16(gpu_info.device_id()).c_str(), base::UintToString16(gpu_info.device_id()).c_str(),
gpu_info.driver_version().c_str(), UTF8ToUTF16(gpu_info.driver_version()).c_str(),
base::UintToString16(gpu_info.pixel_shader_version()).c_str(), base::UintToString16(gpu_info.pixel_shader_version()).c_str(),
base::UintToString16(gpu_info.vertex_shader_version()).c_str()); base::UintToString16(gpu_info.vertex_shader_version()).c_str());
} }
......
...@@ -8,10 +8,14 @@ GPUInfo::GPUInfo() ...@@ -8,10 +8,14 @@ GPUInfo::GPUInfo()
: progress_(kUninitialized), : progress_(kUninitialized),
vendor_id_(0), vendor_id_(0),
device_id_(0), device_id_(0),
driver_version_(L""), driver_vendor_(""),
driver_version_(""),
pixel_shader_version_(0), pixel_shader_version_(0),
vertex_shader_version_(0), vertex_shader_version_(0),
gl_version_(0), gl_version_(0),
gl_version_string_(""),
gl_vendor_(""),
gl_renderer_(""),
can_lose_context_(false) { can_lose_context_(false) {
} }
...@@ -31,7 +35,11 @@ uint32 GPUInfo::device_id() const { ...@@ -31,7 +35,11 @@ uint32 GPUInfo::device_id() const {
return device_id_; return device_id_;
} }
std::wstring GPUInfo::driver_version() const { std::string GPUInfo::driver_vendor() const {
return driver_vendor_;
}
std::string GPUInfo::driver_version() const {
return driver_version_; return driver_version_;
} }
...@@ -47,34 +55,66 @@ uint32 GPUInfo::gl_version() const { ...@@ -47,34 +55,66 @@ uint32 GPUInfo::gl_version() const {
return gl_version_; return gl_version_;
} }
std::string GPUInfo::gl_version_string() const {
return gl_version_string_;
}
std::string GPUInfo::gl_vendor() const {
return gl_vendor_;
}
std::string GPUInfo::gl_renderer() const {
return gl_renderer_;
}
bool GPUInfo::can_lose_context() const { bool GPUInfo::can_lose_context() const {
return can_lose_context_; return can_lose_context_;
} }
void GPUInfo::SetProgress(Progress progress) {
progress_ = progress;
}
void GPUInfo::SetInitializationTime( void GPUInfo::SetInitializationTime(
const base::TimeDelta& initialization_time) { const base::TimeDelta& initialization_time) {
initialization_time_ = initialization_time; initialization_time_ = initialization_time;
} }
void GPUInfo::SetVideoCardInfo(uint32 vendor_id, uint32 device_id) {
void GPUInfo::SetGraphicsInfo(uint32 vendor_id, uint32 device_id,
const std::wstring& driver_version,
uint32 pixel_shader_version,
uint32 vertex_shader_version,
uint32 gl_version,
bool can_lose_context) {
vendor_id_ = vendor_id; vendor_id_ = vendor_id;
device_id_ = device_id; device_id_ = device_id;
}
void GPUInfo::SetDriverInfo(const std::string& driver_vendor,
const std::string& driver_version) {
driver_vendor_ = driver_vendor;
driver_version_ = driver_version; driver_version_ = driver_version;
}
void GPUInfo::SetShaderVersion(uint32 pixel_shader_version,
uint32 vertex_shader_version) {
pixel_shader_version_ = pixel_shader_version; pixel_shader_version_ = pixel_shader_version;
vertex_shader_version_ = vertex_shader_version; vertex_shader_version_ = vertex_shader_version;
}
void GPUInfo::SetGLVersion(uint32 gl_version) {
gl_version_ = gl_version; gl_version_ = gl_version;
can_lose_context_ = can_lose_context;
} }
void GPUInfo::SetProgress(Progress progress) { void GPUInfo::SetGLVersionString(const std::string& gl_version_string) {
progress_ = progress; gl_version_string_ = gl_version_string;
}
void GPUInfo::SetGLVendor(const std::string& gl_vendor) {
gl_vendor_ = gl_vendor;
}
void GPUInfo::SetGLRenderer(const std::string& gl_renderer) {
gl_renderer_ = gl_renderer;
}
void GPUInfo::SetCanLoseContext(bool can_lose_context) {
can_lose_context_ = can_lose_context;
} }
#if defined(OS_WIN) #if defined(OS_WIN)
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <string> #include <string>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/scoped_ptr.h"
#include "base/time.h" #include "base/time.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/common/dx_diag_node.h" #include "chrome/common/dx_diag_node.h"
...@@ -42,27 +43,42 @@ class GPUInfo { ...@@ -42,27 +43,42 @@ class GPUInfo {
// Device ids are unique to vendor, not to one another. // Device ids are unique to vendor, not to one another.
uint32 device_id() const; uint32 device_id() const;
// Return the vendor of the graphics driver currently installed.
std::string driver_vendor() const;
// Return the version of the graphics driver currently installed. // Return the version of the graphics driver currently installed.
// This will typically be something std::string driver_version() const;
std::wstring driver_version() const;
// Return the version of the pixel/fragment shader used by the gpu. // Return the version of the pixel/fragment shader used by the gpu.
// This will typically be a number less than 10 so storing as a float // Major version in the second lowest 8 bits, minor in the lowest 8 bits,
// should be okay. // eg version 2.5 would be 0x00000205.
uint32 pixel_shader_version() const; uint32 pixel_shader_version() const;
// Return the version of the vertex shader used by the gpu. // Return the version of the vertex shader used by the gpu.
// This will typically be a number less than 10 so storing as a float // Major version in the second lowest 8 bits, minor in the lowest 8 bits,
// should be okay. // eg version 2.5 would be 0x00000205.
uint32 vertex_shader_version() const; uint32 vertex_shader_version() const;
// Return the version of OpenGL we are using. // Return the version of OpenGL we are using.
// Major version in the high word, minor in the low word, eg version 2.5 // Major version in the second lowest 8 bits, minor in the lowest 8 bits,
// would be 0x00020005. // eg version 2.5 would be 0x00000205.
// Returns 0 if we're not using OpenGL, say because we're going through // Returns 0 if we're not using OpenGL, say because we're going through
// D3D instead. // D3D instead.
// TODO(zmo): should be able to tell if it's GL or GLES.
uint32 gl_version() const; uint32 gl_version() const;
// Return the GL_VERSION string.
// Return "" if we are not using OpenGL.
std::string gl_version_string() const;
// Return the GL_VENDOR string.
// Return "" if we are not using OpenGL.
std::string gl_vendor() const;
// Return the GL_RENDERER string.
// Return "" if we are not using OpenGL.
std::string gl_renderer() const;
// Return the device semantics, i.e. whether the Vista and Windows 7 specific // Return the device semantics, i.e. whether the Vista and Windows 7 specific
// semantics are available. // semantics are available.
bool can_lose_context() const; bool can_lose_context() const;
...@@ -71,13 +87,23 @@ class GPUInfo { ...@@ -71,13 +87,23 @@ class GPUInfo {
void SetInitializationTime(const base::TimeDelta& initialization_time); void SetInitializationTime(const base::TimeDelta& initialization_time);
// Populate variables with passed in values void SetVideoCardInfo(uint32 vendor_id, uint32 device_id);
void SetGraphicsInfo(uint32 vendor_id, uint32 device_id,
const std::wstring& driver_version, void SetDriverInfo(const std::string& driver_vendor,
uint32 pixel_shader_version, const std::string& driver_version);
uint32 vertex_shader_version,
uint32 gl_version, void SetShaderVersion(uint32 pixel_shader_version,
bool can_lose_context); uint32 vertex_shader_version);
void SetGLVersion(uint32 gl_version);
void SetGLVersionString(const std::string& gl_vendor_string);
void SetGLVendor(const std::string& gl_vendor);
void SetGLRenderer(const std::string& gl_renderer);
void SetCanLoseContext(bool can_lose_context);
#if defined(OS_WIN) #if defined(OS_WIN)
// The information returned by the DirectX Diagnostics Tool. // The information returned by the DirectX Diagnostics Tool.
...@@ -91,10 +117,14 @@ class GPUInfo { ...@@ -91,10 +117,14 @@ class GPUInfo {
base::TimeDelta initialization_time_; base::TimeDelta initialization_time_;
uint32 vendor_id_; uint32 vendor_id_;
uint32 device_id_; uint32 device_id_;
std::wstring driver_version_; std::string driver_vendor_;
std::string driver_version_;
uint32 pixel_shader_version_; uint32 pixel_shader_version_;
uint32 vertex_shader_version_; uint32 vertex_shader_version_;
uint32 gl_version_; uint32 gl_version_;
std::string gl_version_string_;
std::string gl_vendor_;
std::string gl_renderer_;
bool can_lose_context_; bool can_lose_context_;
#if defined(OS_WIN) #if defined(OS_WIN)
......
...@@ -8,9 +8,17 @@ ...@@ -8,9 +8,17 @@
// Test that an empty GPUInfo has valid members // Test that an empty GPUInfo has valid members
TEST(GPUInfoBasicTest, EmptyGPUInfo) { TEST(GPUInfoBasicTest, EmptyGPUInfo) {
GPUInfo gpu_info; GPUInfo gpu_info;
EXPECT_EQ(gpu_info.progress(), GPUInfo::kUninitialized);
EXPECT_EQ(gpu_info.initialization_time().ToInternalValue(), 0);
EXPECT_EQ(gpu_info.vendor_id(), 0u); EXPECT_EQ(gpu_info.vendor_id(), 0u);
EXPECT_EQ(gpu_info.device_id(), 0u); EXPECT_EQ(gpu_info.device_id(), 0u);
EXPECT_EQ(gpu_info.driver_version(), L""); EXPECT_EQ(gpu_info.driver_vendor(), "");
EXPECT_EQ(gpu_info.driver_version(), "");
EXPECT_EQ(gpu_info.pixel_shader_version(), 0u); EXPECT_EQ(gpu_info.pixel_shader_version(), 0u);
EXPECT_EQ(gpu_info.vertex_shader_version(), 0u); EXPECT_EQ(gpu_info.vertex_shader_version(), 0u);
EXPECT_EQ(gpu_info.gl_version(), 0u);
EXPECT_EQ(gpu_info.gl_version_string(), "");
EXPECT_EQ(gpu_info.gl_vendor(), "");
EXPECT_EQ(gpu_info.gl_renderer(), "");
EXPECT_EQ(gpu_info.can_lose_context(), false);
} }
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "base/string_piece.h"
#include "base/sys_string_conversions.h"
#include "chrome/common/gpu_create_command_buffer_config.h" #include "chrome/common/gpu_create_command_buffer_config.h"
#include "chrome/common/gpu_info.h" #include "chrome/common/gpu_info.h"
#include "chrome/common/dx_diag_node.h" #include "chrome/common/dx_diag_node.h"
...@@ -130,10 +132,14 @@ void ParamTraits<GPUInfo> ::Write(Message* m, const param_type& p) { ...@@ -130,10 +132,14 @@ void ParamTraits<GPUInfo> ::Write(Message* m, const param_type& p) {
WriteParam(m, p.initialization_time()); WriteParam(m, p.initialization_time());
WriteParam(m, p.vendor_id()); WriteParam(m, p.vendor_id());
WriteParam(m, p.device_id()); WriteParam(m, p.device_id());
WriteParam(m, p.driver_vendor());
WriteParam(m, p.driver_version()); WriteParam(m, p.driver_version());
WriteParam(m, p.pixel_shader_version()); WriteParam(m, p.pixel_shader_version());
WriteParam(m, p.vertex_shader_version()); WriteParam(m, p.vertex_shader_version());
WriteParam(m, p.gl_version()); WriteParam(m, p.gl_version());
WriteParam(m, p.gl_version_string());
WriteParam(m, p.gl_vendor());
WriteParam(m, p.gl_renderer());
WriteParam(m, p.can_lose_context()); WriteParam(m, p.can_lose_context());
#if defined(OS_WIN) #if defined(OS_WIN)
...@@ -146,32 +152,41 @@ bool ParamTraits<GPUInfo> ::Read(const Message* m, void** iter, param_type* p) { ...@@ -146,32 +152,41 @@ bool ParamTraits<GPUInfo> ::Read(const Message* m, void** iter, param_type* p) {
base::TimeDelta initialization_time; base::TimeDelta initialization_time;
uint32 vendor_id; uint32 vendor_id;
uint32 device_id; uint32 device_id;
std::wstring driver_version; std::string driver_vendor;
std::string driver_version;
uint32 pixel_shader_version; uint32 pixel_shader_version;
uint32 vertex_shader_version; uint32 vertex_shader_version;
uint32 gl_version; uint32 gl_version;
std::string gl_version_string;
std::string gl_vendor;
std::string gl_renderer;
bool can_lose_context; bool can_lose_context;
bool ret = ReadParam(m, iter, &progress); bool ret = ReadParam(m, iter, &progress);
ret = ret && ReadParam(m, iter, &initialization_time); ret = ret && ReadParam(m, iter, &initialization_time);
ret = ret && ReadParam(m, iter, &vendor_id); ret = ret && ReadParam(m, iter, &vendor_id);
ret = ret && ReadParam(m, iter, &device_id); ret = ret && ReadParam(m, iter, &device_id);
ret = ret && ReadParam(m, iter, &driver_vendor);
ret = ret && ReadParam(m, iter, &driver_version); ret = ret && ReadParam(m, iter, &driver_version);
ret = ret && ReadParam(m, iter, &pixel_shader_version); ret = ret && ReadParam(m, iter, &pixel_shader_version);
ret = ret && ReadParam(m, iter, &vertex_shader_version); ret = ret && ReadParam(m, iter, &vertex_shader_version);
ret = ret && ReadParam(m, iter, &gl_version); ret = ret && ReadParam(m, iter, &gl_version);
ret = ret && ReadParam(m, iter, &gl_version_string);
ret = ret && ReadParam(m, iter, &gl_vendor);
ret = ret && ReadParam(m, iter, &gl_renderer);
ret = ret && ReadParam(m, iter, &can_lose_context); ret = ret && ReadParam(m, iter, &can_lose_context);
p->SetProgress(static_cast<GPUInfo::Progress>(progress)); p->SetProgress(static_cast<GPUInfo::Progress>(progress));
if (!ret) if (!ret)
return false; return false;
p->SetInitializationTime(initialization_time); p->SetInitializationTime(initialization_time);
p->SetGraphicsInfo(vendor_id, p->SetVideoCardInfo(vendor_id, device_id);
device_id, p->SetDriverInfo(driver_vendor, driver_version);
driver_version, p->SetShaderVersion(pixel_shader_version, vertex_shader_version);
pixel_shader_version, p->SetGLVersion(gl_version);
vertex_shader_version, p->SetGLVersionString(gl_version_string);
gl_version, p->SetGLVendor(gl_vendor);
can_lose_context); p->SetGLRenderer(gl_renderer);
p->SetCanLoseContext(can_lose_context);
#if defined(OS_WIN) #if defined(OS_WIN)
DxDiagNode dx_diagnostics; DxDiagNode dx_diagnostics;
...@@ -185,13 +200,17 @@ bool ParamTraits<GPUInfo> ::Read(const Message* m, void** iter, param_type* p) { ...@@ -185,13 +200,17 @@ bool ParamTraits<GPUInfo> ::Read(const Message* m, void** iter, param_type* p) {
} }
void ParamTraits<GPUInfo> ::Log(const param_type& p, std::string* l) { void ParamTraits<GPUInfo> ::Log(const param_type& p, std::string* l) {
l->append(base::StringPrintf("<GPUInfo> %d %d %x %x %ls %d", l->append(base::StringPrintf("<GPUInfo> %d %d %x %x %s %s %x %x %x %d",
p.progress(), p.progress(),
static_cast<int32>( static_cast<int32>(
p.initialization_time().InMilliseconds()), p.initialization_time().InMilliseconds()),
p.vendor_id(), p.vendor_id(),
p.device_id(), p.device_id(),
p.driver_vendor().c_str(),
p.driver_version().c_str(), p.driver_version().c_str(),
p.pixel_shader_version(),
p.vertex_shader_version(),
p.gl_version(),
p.can_lose_context())); p.can_lose_context()));
} }
......
...@@ -12,14 +12,17 @@ ...@@ -12,14 +12,17 @@
// Test GPUInfo serialization // Test GPUInfo serialization
TEST(GPUIPCMessageTest, GPUInfo) { TEST(GPUIPCMessageTest, GPUInfo) {
GPUInfo input; GPUInfo input;
// Test variables taken from Lenovo T61 // Test variables taken from HP Z600 Workstation
input.SetProgress(GPUInfo::kPartial); input.SetProgress(GPUInfo::kPartial);
input.SetInitializationTime(base::TimeDelta::FromMilliseconds(100)); input.SetInitializationTime(base::TimeDelta::FromMilliseconds(100));
input.SetGraphicsInfo(0x10de, 0x429, L"6.14.11.7715", input.SetVideoCardInfo(0x10de, 0x0658);
0xffff0300, input.SetDriverInfo("NVIDIA", "195.36.24");
0xfffe0300, input.SetShaderVersion(0x0162, 0x0162);
0x00010005, input.SetGLVersion(0x0302);
true); input.SetGLVersionString("3.2.0 NVIDIA 195.36.24");
input.SetGLVendor("NVIDIA Corporation");
input.SetGLRenderer("Quadro FX 380/PCI/SSE2");
input.SetCanLoseContext(false);
IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL); IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
IPC::WriteParam(&msg, input); IPC::WriteParam(&msg, input);
...@@ -32,13 +35,18 @@ TEST(GPUIPCMessageTest, GPUInfo) { ...@@ -32,13 +35,18 @@ TEST(GPUIPCMessageTest, GPUInfo) {
output.initialization_time().InMilliseconds()); output.initialization_time().InMilliseconds());
EXPECT_EQ(input.vendor_id(), output.vendor_id()); EXPECT_EQ(input.vendor_id(), output.vendor_id());
EXPECT_EQ(input.device_id(), output.device_id()); EXPECT_EQ(input.device_id(), output.device_id());
EXPECT_EQ(input.driver_vendor(), output.driver_vendor());
EXPECT_EQ(input.driver_version(), output.driver_version()); EXPECT_EQ(input.driver_version(), output.driver_version());
EXPECT_EQ(input.pixel_shader_version(), output.pixel_shader_version()); EXPECT_EQ(input.pixel_shader_version(), output.pixel_shader_version());
EXPECT_EQ(input.vertex_shader_version(), output.vertex_shader_version()); EXPECT_EQ(input.vertex_shader_version(), output.vertex_shader_version());
EXPECT_EQ(input.gl_version(), output.gl_version()); EXPECT_EQ(input.gl_version(), output.gl_version());
EXPECT_EQ(input.gl_version_string(), output.gl_version_string());
EXPECT_EQ(input.gl_vendor(), output.gl_vendor());
EXPECT_EQ(input.gl_renderer(), output.gl_renderer());
EXPECT_EQ(input.can_lose_context(), output.can_lose_context()); EXPECT_EQ(input.can_lose_context(), output.can_lose_context());
std::string log_message; std::string log_message;
IPC::LogParam(output, &log_message); IPC::LogParam(output, &log_message);
EXPECT_STREQ("<GPUInfo> 1 100 10de 429 6.14.11.7715 1", log_message.c_str()); EXPECT_STREQ("<GPUInfo> 1 100 10de 658 NVIDIA 195.36.24 162 162 302 0",
log_message.c_str());
} }
// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/gpu/gpu_info_collector.h"
#include <string>
#include <vector>
#include "app/gfx/gl/gl_bindings.h"
#include "app/gfx/gl/gl_context.h"
#include "base/logging.h"
#include "base/string_number_conversions.h"
#include "base/string_piece.h"
#include "base/string_split.h"
namespace {
// This creates an offscreen GL context for gl queries. Returned GLContext
// should be deleted in FinalizeGLContext.
gfx::GLContext* InitializeGLContext() {
if (!gfx::GLContext::InitializeOneOff()) {
LOG(ERROR) << "gfx::GLContext::InitializeOneOff() failed";
return NULL;
}
gfx::GLContext* context = gfx::GLContext::CreateOffscreenGLContext(NULL);
if (context == NULL) {
LOG(ERROR) << "gfx::GLContext::CreateOffscreenGLContext(NULL) failed";
return NULL;
}
if (!context->MakeCurrent()) {
LOG(ERROR) << "gfx::GLContext::MakeCurrent() failed";
context->Destroy();
delete context;
return NULL;
}
return context;
}
// This destroy and delete the GL context.
void FinalizeGLContext(gfx::GLContext** context) {
DCHECK(context);
if (*context) {
(*context)->Destroy();
delete *context;
*context = NULL;
}
}
std::string GetGLString(unsigned int pname) {
const char* gl_string =
reinterpret_cast<const char*>(glGetString(pname));
if (gl_string)
return std::string(gl_string);
return "";
}
uint32 GetVersionNumberFromString(const std::string& version_string) {
int major = 0, minor = 0;
size_t begin = version_string.find_first_of("0123456789");
if (begin != std::string::npos) {
size_t end = version_string.find_first_not_of("01234567890.", begin);
std::string sub_string;
if (end != std::string::npos)
sub_string = version_string.substr(begin, end - begin);
else
sub_string = version_string.substr(begin);
std::vector<std::string> pieces;
base::SplitString(sub_string, '.', &pieces);
if (pieces.size() >= 2) {
base::StringToInt(pieces[0], &major);
base::StringToInt(pieces[1], &minor);
}
}
return ((major << 8) + minor);
}
} // namespace anonymous
namespace gpu_info_collector {
bool CollectGraphicsInfoGL(GPUInfo* gpu_info) {
DCHECK(gpu_info);
gfx::GLContext* context = InitializeGLContext();
if (context == NULL)
return false;
gpu_info->SetGLRenderer(GetGLString(GL_RENDERER));
gpu_info->SetGLVendor(GetGLString(GL_VENDOR));
gpu_info->SetGLVersionString(GetGLString(GL_VERSION));
bool validGLVersionInfo = CollectGLVersionInfo(gpu_info);
bool validVideoCardInfo = CollectVideoCardInfo(gpu_info);
bool validDriverInfo = CollectDriverInfo(gpu_info);
FinalizeGLContext(&context);
return (validGLVersionInfo && validVideoCardInfo && validDriverInfo);
}
bool CollectGLVersionInfo(GPUInfo* gpu_info) {
DCHECK(gpu_info);
std::string gl_version_string = gpu_info->gl_version_string();
std::string glsl_version_string =
GetGLString(GL_SHADING_LANGUAGE_VERSION);
uint32 gl_version = GetVersionNumberFromString(gl_version_string);
gpu_info->SetGLVersion(gl_version);
uint32 glsl_version = GetVersionNumberFromString(glsl_version_string);
gpu_info->SetShaderVersion(glsl_version, glsl_version);
return true;
}
} // namespace gpu_info_collector
...@@ -27,13 +27,22 @@ bool CollectGraphicsInfo(GPUInfo* gpu_info); ...@@ -27,13 +27,22 @@ bool CollectGraphicsInfo(GPUInfo* gpu_info);
// A D3D argument is passed in for testing purposes // A D3D argument is passed in for testing purposes
bool CollectGraphicsInfoD3D(IDirect3D9* d3d, GPUInfo* gpu_info); bool CollectGraphicsInfoD3D(IDirect3D9* d3d, GPUInfo* gpu_info);
// The GL version of collecting information
bool CollectGraphicsInfoGL(GPUInfo* gpu_info);
// Collect the DirectX Disagnostics information about the attached displays. // Collect the DirectX Disagnostics information about the attached displays.
bool GetDxDiagnostics(DxDiagNode* output); bool GetDxDiagnostics(DxDiagNode* output);
#endif #endif
// All platforms have a GL version for collecting information
bool CollectGraphicsInfoGL(GPUInfo* gpu_info);
// Collect GL and Shading language version information
bool CollectGLVersionInfo(GPUInfo* gpu_info);
// Platform specific method for collecting vendor and device ids
bool CollectVideoCardInfo(GPUInfo* gpu_info);
// Each platform stores the driver version on the GL_VERSION string differently
bool CollectDriverInfo(GPUInfo* gpu_info);
} // namespace gpu_info_collector } // namespace gpu_info_collector
#endif // CHROME_GPU_GPU_INFO_COLLECTOR_H__ #endif // CHROME_GPU_GPU_INFO_COLLECTOR_H__
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#include "app/gfx/gl/gl_implementation.h" #include "app/gfx/gl/gl_implementation.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/scoped_ptr.h" #include "base/scoped_ptr.h"
#include "base/string_piece.h"
#include "base/string_split.h"
#include "base/string_util.h" #include "base/string_util.h"
namespace { namespace {
...@@ -113,40 +115,11 @@ PciInterface* InitializeLibPci(const char* lib_name) { ...@@ -113,40 +115,11 @@ PciInterface* InitializeLibPci(const char* lib_name) {
} }
// This close the dynamically opened libpci and delete the interface. // This close the dynamically opened libpci and delete the interface.
void FinalizeLibPci(PciInterface*& interface) { void FinalizeLibPci(PciInterface** interface) {
DCHECK(interface != NULL && interface->lib_handle != NULL); DCHECK(interface && *interface && (*interface)->lib_handle);
dlclose(interface->lib_handle); dlclose((*interface)->lib_handle);
delete interface; delete (*interface);
interface = NULL; *interface = NULL;
}
// This creates an offscreen GL context for gl queries. Returned GLContext
// should be deleted in FinalizeGLContext.
gfx::GLContext* InitializeGLContext() {
if (!gfx::GLContext::InitializeOneOff()) {
LOG(ERROR) << "gfx::GLContext::InitializeOneOff() failed";
return NULL;
}
gfx::GLContext* context = gfx::GLContext::CreateOffscreenGLContext(NULL);
if (context == NULL) {
LOG(ERROR) << "gfx::GLContext::CreateOffscreenGLContext(NULL) failed";
return NULL;
}
if (!context->MakeCurrent()) {
LOG(ERROR) << "gfx::GLContext::MakeCurrent() failed";
context->Destroy();
delete context;
return NULL;
}
return context;
}
// This destroy and delete the GL context.
void FinalizeGLContext(gfx::GLContext*& context) {
DCHECK(context != NULL);
context->Destroy();
delete context;
context = NULL;
} }
} // namespace anonymous } // namespace anonymous
...@@ -154,25 +127,23 @@ void FinalizeGLContext(gfx::GLContext*& context) { ...@@ -154,25 +127,23 @@ void FinalizeGLContext(gfx::GLContext*& context) {
namespace gpu_info_collector { namespace gpu_info_collector {
bool CollectGraphicsInfo(GPUInfo* gpu_info) { bool CollectGraphicsInfo(GPUInfo* gpu_info) {
gfx::GLContext* context = InitializeGLContext(); DCHECK(gpu_info);
if (context == NULL)
return false; // TODO(zmo): need to consider the case where we are running on top of
// desktop GL and GL_ARB_robustness extension is available.
gpu_info->SetCanLoseContext(
gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2);
gpu_info->SetProgress(GPUInfo::kComplete);
return CollectGraphicsInfoGL(gpu_info);
}
// TODO(zmo): collect driver version, pixel shader version, vertex shader bool CollectVideoCardInfo(GPUInfo* gpu_info) {
// version, and gl version. DCHECK(gpu_info);
std::wstring driver_version = L"";
uint32 pixel_shader_version = 0;
uint32 vertex_shader_version = 0;
uint32 gl_version = 0;
bool can_lose_context =
(gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2);
// TODO(zmo): be more flexible about library name. // TODO(zmo): be more flexible about library name.
PciInterface* interface = InitializeLibPci("libpci.so.3"); PciInterface* interface = InitializeLibPci("libpci.so.3");
if (interface == NULL) { if (interface == NULL)
FinalizeGLContext(context);
return false; return false;
}
PciAccess* access = (interface->pci_alloc)(); PciAccess* access = (interface->pci_alloc)();
DCHECK(access != NULL); DCHECK(access != NULL);
...@@ -183,6 +154,7 @@ bool CollectGraphicsInfo(GPUInfo* gpu_info) { ...@@ -183,6 +154,7 @@ bool CollectGraphicsInfo(GPUInfo* gpu_info) {
for (PciDevice* device = access->device_list; for (PciDevice* device = access->device_list;
device != NULL; device = device->next) { device != NULL; device = device->next) {
(interface->pci_fill_info)(device, 33); // Fill the IDs and class fields. (interface->pci_fill_info)(device, 33); // Fill the IDs and class fields.
// TODO(zmo): there might be other classes that qualify as display devices.
if (device->device_class == 0x0300) { // Device class is DISPLAY_VGA. if (device->device_class == 0x0300) { // Device class is DISPLAY_VGA.
gpu_list.push_back(device); gpu_list.push_back(device);
} }
...@@ -192,10 +164,8 @@ bool CollectGraphicsInfo(GPUInfo* gpu_info) { ...@@ -192,10 +164,8 @@ bool CollectGraphicsInfo(GPUInfo* gpu_info) {
} else { } else {
// If more than one graphics card are identified, find the one that matches // If more than one graphics card are identified, find the one that matches
// gl VENDOR and RENDERER info. // gl VENDOR and RENDERER info.
std::string gl_vendor_string = std::string gl_vendor_string = gpu_info->gl_vendor();
reinterpret_cast<const char*>(glGetString(GL_VENDOR)); std::string gl_renderer_string = gpu_info->gl_renderer();
std::string gl_renderer_string =
reinterpret_cast<const char*>(glGetString(GL_RENDERER));
const int buffer_size = 255; const int buffer_size = 255;
scoped_array<char> buffer(new char[buffer_size]); scoped_array<char> buffer(new char[buffer_size]);
std::vector<PciDevice*> candidates; std::vector<PciDevice*> candidates;
...@@ -240,20 +210,33 @@ bool CollectGraphicsInfo(GPUInfo* gpu_info) { ...@@ -240,20 +210,33 @@ bool CollectGraphicsInfo(GPUInfo* gpu_info) {
if (gpu_active == NULL && candidates.size() == 1) if (gpu_active == NULL && candidates.size() == 1)
gpu_active = candidates[0]; gpu_active = candidates[0];
} }
if (gpu_active != NULL) { if (gpu_active != NULL)
gpu_info->SetGraphicsInfo(gpu_active->vendor_id, gpu_info->SetVideoCardInfo(gpu_active->vendor_id, gpu_active->device_id);
gpu_active->device_id,
driver_version,
pixel_shader_version,
vertex_shader_version,
gl_version,
can_lose_context);
gpu_info->SetProgress(GPUInfo::kComplete);
}
(interface->pci_cleanup)(access); (interface->pci_cleanup)(access);
FinalizeLibPci(interface); FinalizeLibPci(&interface);
FinalizeGLContext(context);
return (gpu_active != NULL); return (gpu_active != NULL);
} }
bool CollectDriverInfo(GPUInfo* gpu_info) {
DCHECK(gpu_info);
std::string gl_version_string = gpu_info->gl_version_string();
std::vector<std::string> pieces;
base::SplitStringAlongWhitespace(gl_version_string, &pieces);
// In linux, the gl version string might be in the format of
// GLVersion DriverVendor DriverVersion
if (pieces.size() < 3)
return false;
std::string driver_version = pieces[2];
size_t pos = driver_version.find_first_not_of("0123456789.");
if (pos == 0)
return false;
if (pos != std::string::npos)
driver_version = driver_version.substr(0, pos);
gpu_info->SetDriverInfo(pieces[1], driver_version);
return true;
}
} // namespace gpu_info_collector } // namespace gpu_info_collector
...@@ -16,10 +16,10 @@ ...@@ -16,10 +16,10 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <IOKit/IOKitLib.h> #import <IOKit/IOKitLib.h>
namespace gpu_info_collector { namespace {
static CFTypeRef SearchPortForProperty(io_registry_entry_t dspPort, CFTypeRef SearchPortForProperty(io_registry_entry_t dspPort,
CFStringRef propertyName) { CFStringRef propertyName) {
return IORegistryEntrySearchCFProperty(dspPort, return IORegistryEntrySearchCFProperty(dspPort,
kIOServicePlane, kIOServicePlane,
propertyName, propertyName,
...@@ -28,145 +28,65 @@ static CFTypeRef SearchPortForProperty(io_registry_entry_t dspPort, ...@@ -28,145 +28,65 @@ static CFTypeRef SearchPortForProperty(io_registry_entry_t dspPort,
kIORegistryIterateParents); kIORegistryIterateParents);
} }
static void CFReleaseIf(CFTypeRef type_ref) { UInt32 IntValueOfCFData(CFDataRef data_ref) {
if (type_ref) DCHECK(data_ref);
CFRelease(type_ref);
}
static UInt32 IntValueOfCFData(CFDataRef data_ref) {
UInt32 value = 0; UInt32 value = 0;
const UInt32* value_pointer =
if (data_ref) { reinterpret_cast<const UInt32*>(CFDataGetBytePtr(data_ref));
const UInt32 *value_pointer = if (value_pointer != NULL)
reinterpret_cast<const UInt32*>(CFDataGetBytePtr(data_ref)); value = *value_pointer;
if (value_pointer != NULL)
value = *value_pointer;
}
return value; return value;
} }
static void CollectVideoCardInfo(CGDirectDisplayID displayID, } // namespace anonymous
int *vendorID,
int *deviceID) {
io_registry_entry_t dspPort = CGDisplayIOServicePort(displayID);
CFTypeRef vendorIDRef = SearchPortForProperty(dspPort, CFSTR("vendor-id")); namespace gpu_info_collector {
if (vendorID) *vendorID = IntValueOfCFData((CFDataRef)vendorIDRef);
CFTypeRef deviceIDRef = SearchPortForProperty(dspPort, CFSTR("device-id")); bool CollectGraphicsInfo(GPUInfo* gpu_info) {
if (deviceID) *deviceID = IntValueOfCFData((CFDataRef)deviceIDRef); DCHECK(gpu_info);
CFReleaseIf(vendorIDRef); gpu_info->SetCanLoseContext(
CFReleaseIf(deviceIDRef); gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2);
gpu_info->SetProgress(GPUInfo::kComplete);
return CollectGraphicsInfoGL(gpu_info);
} }
// Return a pointer to the last character with value c in string s. bool CollectVideoCardInfo(GPUInfo* gpu_info) {
// Returns NULL if c is not found. DCHECK(gpu_info);
static char* FindLastChar(char *s, char c) {
char *s_found = NULL;
while (*s != '\0') { if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL)
if (*s == c) return false;
s_found = s;
s++;
}
return s_found;
}
// Gets the numeric HLSL version. UInt32 vendor_id = 0, device_id = 0;
// You pass it the current GL major version, to give it a hint where to look. io_registry_entry_t dsp_port = CGDisplayIOServicePort(kCGDirectMainDisplay);
static int GetShaderNumericVersion(int gl_major_version) { CFTypeRef vendor_id_ref = SearchPortForProperty(dsp_port, CFSTR("vendor-id"));
int gl_hlsl_major = 0, gl_hlsl_minor = 0; if (vendor_id_ref) {
int shader_version = 0; vendor_id = IntValueOfCFData((CFDataRef)vendor_id_ref);
CFRelease(vendor_id_ref);
if (gl_major_version == 1) { }
const char *gl_extensions_string = (const char*)glGetString(GL_EXTENSIONS); CFTypeRef device_id_ref = SearchPortForProperty(dsp_port, CFSTR("device-id"));
if (gl_extensions_string && if (device_id_ref) {
strstr(gl_extensions_string, "GL_ARB_shading_language_100")) { device_id = IntValueOfCFData((CFDataRef)device_id_ref);
gl_hlsl_major = 1; CFRelease(device_id_ref);
gl_hlsl_minor = 0;
}
} else if (gl_major_version > 1) {
const char *glsl_version_string =
(const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
if (glsl_version_string)
sscanf(glsl_version_string, "%u.%u", &gl_hlsl_major, &gl_hlsl_minor);
} }
shader_version = (gl_hlsl_major << 8) | (gl_hlsl_minor & 0xFF); gpu_info->SetVideoCardInfo(vendor_id, device_id);
return shader_version; return true;
}
static std::wstring CStringToWString(const char *s) {
base::StringPiece sp(s);
return base::SysUTF8ToWide(sp);
} }
bool CollectDriverInfo(GPUInfo* gpu_info) {
// Returns the driver version string as its value, and also returns the DCHECK(gpu_info);
// gl version and shader language version by setting the arguments pointed to.
static std::wstring CollectGLInfo(int *out_gl_version,
int *out_shader_version) {
int gl_major = 0, gl_minor = 0;
char *gl_version_string = NULL;
std::wstring driver_version;
gl_version_string = (char*)glGetString(GL_VERSION);
sscanf(gl_version_string, "%u.%u", &gl_major, &gl_minor);
*out_gl_version = (gl_major << 8) | (gl_minor & 0xFF);
*out_shader_version = GetShaderNumericVersion(gl_major);
// Extract the OpenGL driver version string from the GL_VERSION string. // Extract the OpenGL driver version string from the GL_VERSION string.
// Mac OpenGL drivers have the driver version // Mac OpenGL drivers have the driver version
// at the end of the gl version string preceded by a dash. // at the end of the gl version string preceded by a dash.
// Use some jiggery-pokery to turn that utf8 string into a std::wstring. // Use some jiggery-pokery to turn that utf8 string into a std::wstring.
char *s = FindLastChar(gl_version_string, '-'); std::string gl_version_string = gpu_info->gl_version_string();
if (s) size_t pos = gl_version_string.find_last_of('-');
driver_version = CStringToWString(s + 1); if (pos == std::string::npos)
return driver_version;
}
bool CollectGraphicsInfo(GPUInfo* gpu_info) {
if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL)
return false; return false;
// Video Card data. gpu_info->SetDriverInfo("", gl_version_string.substr(pos + 1));
int vendor_id = 0, device_id = 0;
// OpenGL data.
std::wstring driver_version = L"";
int gl_version = 0, shader_version = 0;
CollectVideoCardInfo(kCGDirectMainDisplay, &vendor_id, &device_id);
// Temporarily make an offscreen GL context so we can gather info from it.
if (gfx::GLContext::InitializeOneOff()) {
scoped_ptr<gfx::GLContext> ctx(
gfx::GLContext::CreateOffscreenGLContext(NULL));
if (ctx.get()) {
if (ctx->MakeCurrent()) {
driver_version = CollectGLInfo(&gl_version, &shader_version);
}
ctx->Destroy();
}
}
// OpenGL doesn't have separate versions for pixel and vertex shader
// languages, so we just pass the shader_version for both.
gpu_info->SetGraphicsInfo(vendor_id,
device_id,
driver_version,
shader_version,
shader_version,
gl_version,
false);
gpu_info->SetProgress(GPUInfo::kComplete);
return true; return true;
} }
......
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "app/gfx/gl/gl_implementation.h"
#include "base/scoped_ptr.h"
#include "chrome/common/gpu_info.h"
#include "chrome/gpu/gpu_info_collector.h"
#include "gpu/command_buffer/common/gl_mock.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::gfx::MockGLInterface;
using ::testing::Return;
class GPUInfoCollectorTest : public testing::Test {
public:
GPUInfoCollectorTest() {}
virtual ~GPUInfoCollectorTest() { }
void SetUp() {
gfx::InitializeGLBindings(gfx::kGLImplementationMockGL);
gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>());
::gfx::GLInterface::SetGLInterface(gl_.get());
#if defined(OS_WIN)
const uint32 vendor_id = 0x10de;
const uint32 device_id = 0x0658;
const char* driver_vendor = ""; // not implemented
const char* driver_version = "";
const uint32 shader_version = 0x00000128;
const uint32 gl_version = 0x00000301;
const char* gl_renderer = "Quadro FX 380/PCI/SSE2";
const char* gl_vendor = "NVIDIA Corporation";
const char* gl_version_string = "3.1.0";
const char* gl_shading_language_version = "1.40 NVIDIA via Cg compiler";
#elif defined(OS_MACOSX)
const uint32 vendor_id = 0x10de;
const uint32 device_id = 0x0640;
const char* driver_vendor = ""; // not implemented
const char* driver_version = "1.6.18";
const uint32 shader_version = 0x00000114;
const uint32 gl_version = 0x00000201;
const char* gl_renderer = "NVIDIA GeForce GT 120 OpenGL Engine";
const char* gl_vendor = "NVIDIA Corporation";
const char* gl_version_string = "2.1 NVIDIA-1.6.18";
const char* gl_shading_language_version = "1.20 ";
#else // defined (OS_LINUX)
const uint32 vendor_id = 0x10de;
const uint32 device_id = 0x0658;
const char* driver_vendor = "NVIDIA";
const char* driver_version = "195.36.24";
const uint32 shader_version = 0x00000132;
const uint32 gl_version = 0x00000302;
const char* gl_renderer = "Quadro FX 380/PCI/SSE2";
const char* gl_vendor = "NVIDIA Corporation";
const char* gl_version_string = "3.2.0 NVIDIA 195.36.24";
const char* gl_shading_language_version = "1.50 NVIDIA via Cg compiler";
#endif
test_values_.SetVideoCardInfo(vendor_id, device_id);
test_values_.SetDriverInfo(driver_vendor, driver_version);
test_values_.SetShaderVersion(shader_version, shader_version);
test_values_.SetGLVersion(gl_version);
test_values_.SetGLRenderer(gl_renderer);
test_values_.SetGLVendor(gl_vendor);
test_values_.SetGLVersionString(gl_version_string);
test_values_.SetCanLoseContext(false);
EXPECT_CALL(*gl_, GetString(GL_EXTENSIONS))
.WillRepeatedly(Return(reinterpret_cast<const GLubyte*>(
"GL_OES_packed_depth_stencil GL_EXT_texture_format_BGRA8888 "
"GL_EXT_read_format_bgra")));
EXPECT_CALL(*gl_, GetString(GL_SHADING_LANGUAGE_VERSION))
.WillRepeatedly(Return(reinterpret_cast<const GLubyte*>(
gl_shading_language_version)));
EXPECT_CALL(*gl_, GetString(GL_VERSION))
.WillRepeatedly(Return(reinterpret_cast<const GLubyte*>(
gl_version_string)));
EXPECT_CALL(*gl_, GetString(GL_VENDOR))
.WillRepeatedly(Return(reinterpret_cast<const GLubyte*>(
gl_vendor)));
EXPECT_CALL(*gl_, GetString(GL_RENDERER))
.WillRepeatedly(Return(reinterpret_cast<const GLubyte*>(
gl_renderer)));
}
void TearDown() {
::gfx::GLInterface::SetGLInterface(NULL);
gl_.reset();
}
public:
// Use StrictMock to make 100% sure we know how GL will be called.
scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_;
GPUInfo test_values_;
};
// TODO(rlp): Test the vendor and device id collection if deemed necessary as
// it involves several complicated mocks for each platform.
TEST_F(GPUInfoCollectorTest, DriverVendorGL) {
GPUInfo gpu_info;
gpu_info_collector::CollectGraphicsInfoGL(&gpu_info);
std::string driver_vendor = gpu_info.driver_vendor();
EXPECT_EQ(test_values_.driver_vendor(), driver_vendor);
}
TEST_F(GPUInfoCollectorTest, DriverVersionGL) {
GPUInfo gpu_info;
gpu_info_collector::CollectGraphicsInfoGL(&gpu_info);
std::string driver_version = gpu_info.driver_version();
EXPECT_EQ(test_values_.driver_version(), driver_version);
}
TEST_F(GPUInfoCollectorTest, PixelShaderVersionGL) {
GPUInfo gpu_info;
gpu_info_collector::CollectGraphicsInfoGL(&gpu_info);
uint32 ps_version = gpu_info.pixel_shader_version();
EXPECT_EQ(test_values_.pixel_shader_version(), ps_version);
}
TEST_F(GPUInfoCollectorTest, VertexShaderVersionGL) {
GPUInfo gpu_info;
gpu_info_collector::CollectGraphicsInfoGL(&gpu_info);
uint32 vs_version = gpu_info.vertex_shader_version();
EXPECT_EQ(test_values_.vertex_shader_version(), vs_version);
}
TEST_F(GPUInfoCollectorTest, GLVersionGL) {
GPUInfo gpu_info;
gpu_info_collector::CollectGraphicsInfoGL(&gpu_info);
uint32 gl_version = gpu_info.gl_version();
EXPECT_EQ(test_values_.gl_version(), gl_version);
}
TEST_F(GPUInfoCollectorTest, GLVersionStringGL) {
GPUInfo gpu_info;
gpu_info_collector::CollectGraphicsInfoGL(&gpu_info);
std::string gl_version_string = gpu_info.gl_version_string();
EXPECT_EQ(test_values_.gl_version_string(), gl_version_string);
}
TEST_F(GPUInfoCollectorTest, GLRendererGL) {
GPUInfo gpu_info;
gpu_info_collector::CollectGraphicsInfoGL(&gpu_info);
std::string gl_renderer = gpu_info.gl_renderer();
EXPECT_EQ(test_values_.gl_renderer(), gl_renderer);
}
TEST_F(GPUInfoCollectorTest, GLVendorGL) {
GPUInfo gpu_info;
gpu_info_collector::CollectGraphicsInfoGL(&gpu_info);
std::string gl_vendor = gpu_info.gl_vendor();
EXPECT_EQ(test_values_.gl_vendor(), gl_vendor);
}
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "app/gfx/gl/gl_implementation.h" #include "app/gfx/gl/gl_implementation.h"
#include "base/file_path.h" #include "base/file_path.h"
#include "base/scoped_native_library.h" #include "base/scoped_native_library.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h" #include "base/string_util.h"
// ANGLE seems to require that main.h be included before any other ANGLE header. // ANGLE seems to require that main.h be included before any other ANGLE header.
...@@ -20,9 +21,15 @@ ...@@ -20,9 +21,15 @@
namespace gpu_info_collector { namespace gpu_info_collector {
bool CollectGraphicsInfo(GPUInfo* gpu_info) { bool CollectGraphicsInfo(GPUInfo* gpu_info) {
// TODO: collect OpenGL info if not using ANGLE? DCHECK(gpu_info);
if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2)
return true; if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
gpu_info->SetProgress(GPUInfo::kComplete);
return CollectGraphicsInfoGL(gpu_info);
}
// TODO(zmo): the following code only works if running on top of ANGLE.
// Need to handle the case when running on top of real EGL/GLES2 drivers.
egl::Display* display = static_cast<egl::Display*>( egl::Display* display = static_cast<egl::Display*>(
gfx::BaseEGLContext::GetDisplay()); gfx::BaseEGLContext::GetDisplay());
...@@ -43,7 +50,6 @@ bool CollectGraphicsInfo(GPUInfo* gpu_info) { ...@@ -43,7 +50,6 @@ bool CollectGraphicsInfo(GPUInfo* gpu_info) {
// DirectX diagnostics are collected asynchronously because it takes a // DirectX diagnostics are collected asynchronously because it takes a
// couple of seconds. Do not mark as complete until that is done. // couple of seconds. Do not mark as complete until that is done.
gpu_info->SetProgress(GPUInfo::kPartial); gpu_info->SetProgress(GPUInfo::kPartial);
return true; return true;
} }
...@@ -51,35 +57,39 @@ bool CollectGraphicsInfoD3D(IDirect3D9* d3d, GPUInfo* gpu_info) { ...@@ -51,35 +57,39 @@ bool CollectGraphicsInfoD3D(IDirect3D9* d3d, GPUInfo* gpu_info) {
DCHECK(d3d); DCHECK(d3d);
DCHECK(gpu_info); DCHECK(gpu_info);
// Get device information bool succeed = true;
// Get device/driver information
D3DADAPTER_IDENTIFIER9 identifier; D3DADAPTER_IDENTIFIER9 identifier;
HRESULT hr = d3d->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &identifier); if (d3d->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &identifier) == D3D_OK) {
if (hr != D3D_OK) { gpu_info->SetVideoCardInfo(identifier.VendorId, identifier.DeviceId);
d3d->Release();
return false; uint32 driver_major_version_hi = HIWORD(identifier.DriverVersion.HighPart);
uint32 driver_major_version_lo = LOWORD(identifier.DriverVersion.HighPart);
uint32 driver_minor_version_hi = HIWORD(identifier.DriverVersion.LowPart);
uint32 driver_minor_version_lo = LOWORD(identifier.DriverVersion.LowPart);
std::string driver_version = StringPrintf("%d.%d.%d.%d",
driver_major_version_hi,
driver_major_version_lo,
driver_minor_version_hi,
driver_minor_version_lo);
gpu_info->SetDriverInfo("", driver_version);
} else {
succeed = false;
} }
uint32 vendor_id = identifier.VendorId;
uint32 device_id = identifier.DeviceId;
// Get version information // Get version information
D3DCAPS9 d3d_caps; D3DCAPS9 d3d_caps;
HRESULT caps_result = d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, if (d3d->GetDeviceCaps(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, D3DDEVTYPE_HAL,
&d3d_caps); &d3d_caps) == D3D_OK) {
if (caps_result != D3D_OK) { gpu_info->SetShaderVersion(d3d_caps.PixelShaderVersion,
d3d->Release(); d3d_caps.VertexShaderVersion);
return false; } else {
succeed = false;
} }
uint32 driver_major_version_hi = HIWORD(identifier.DriverVersion.HighPart);
uint32 driver_major_version_lo = LOWORD(identifier.DriverVersion.HighPart);
uint32 driver_minor_version_hi = HIWORD(identifier.DriverVersion.LowPart);
uint32 driver_minor_version_lo = LOWORD(identifier.DriverVersion.LowPart);
std::wstring driver_version = StringPrintf(L"%d.%d.%d.%d",
driver_major_version_hi,
driver_major_version_lo,
driver_minor_version_hi,
driver_minor_version_lo);
// Get can_lose_context
bool can_lose_context = false; bool can_lose_context = false;
IDirect3D9Ex* d3dex = NULL; IDirect3D9Ex* d3dex = NULL;
if (SUCCEEDED(d3d->QueryInterface(__uuidof(IDirect3D9Ex), if (SUCCEEDED(d3d->QueryInterface(__uuidof(IDirect3D9Ex),
...@@ -88,24 +98,15 @@ bool CollectGraphicsInfoD3D(IDirect3D9* d3d, GPUInfo* gpu_info) { ...@@ -88,24 +98,15 @@ bool CollectGraphicsInfoD3D(IDirect3D9* d3d, GPUInfo* gpu_info) {
} else { } else {
can_lose_context = true; can_lose_context = true;
} }
gpu_info->SetCanLoseContext(can_lose_context);
d3d->Release(); d3d->Release();
// Get shader versions
uint32 pixel_shader_version = d3d_caps.PixelShaderVersion;
uint32 vertex_shader_version = d3d_caps.VertexShaderVersion;
gpu_info->SetGraphicsInfo(vendor_id,
device_id,
driver_version,
pixel_shader_version,
vertex_shader_version,
0,
can_lose_context);
return true; return true;
} }
bool CollectGraphicsInfoGL(GPUInfo* gpu_info) { bool CollectVideoCardInfo(GPUInfo* gpu_info) {
DCHECK(gpu_info);
// Taken from http://developer.nvidia.com/object/device_ids.html // Taken from http://developer.nvidia.com/object/device_ids.html
DISPLAY_DEVICE dd; DISPLAY_DEVICE dd;
dd.cb = sizeof(DISPLAY_DEVICE); dd.cb = sizeof(DISPLAY_DEVICE);
...@@ -117,27 +118,33 @@ bool CollectGraphicsInfoGL(GPUInfo* gpu_info) { ...@@ -117,27 +118,33 @@ bool CollectGraphicsInfoGL(GPUInfo* gpu_info) {
break; break;
} }
} }
if (id.empty()) {
return false; if (id.length() > 20) {
int vendor_id = 0, device_id = 0;
std::wstring vendor_id_string = id.substr(8, 4);
std::wstring device_id_string = id.substr(17, 4);
base::HexStringToInt(WideToASCII(vendor_id_string), &vendor_id);
base::HexStringToInt(WideToASCII(device_id_string), &device_id);
gpu_info->SetVideoCardInfo(vendor_id, device_id);
return true;
} }
uint32 vendor_id; return false;
uint32 device_id; }
std::wstring vendorid = id.substr(8, 4);
std::wstring deviceid = id.substr(17, 4);
swscanf_s(vendorid.c_str(), L"%x", &vendor_id);
swscanf_s(deviceid.c_str(), L"%x", &device_id);
std::wstring driver_version = L"";
uint32 pixel_shader_version = 0;
uint32 vertex_shader_version = 0;
gpu_info->SetGraphicsInfo(vendor_id, device_id, driver_version,
pixel_shader_version,
vertex_shader_version,
0, // GL version of 0 indicates D3D
false);
return true;
// TODO(rlp): Add driver and pixel versions bool CollectDriverInfo(GPUInfo* gpu_info) {
DCHECK(gpu_info);
std::string gl_version_string = gpu_info->gl_version_string();
// TODO(zmo): We assume the driver version is in the end of GL_VERSION
// string. Need to verify if it is true for majority drivers.
size_t pos = gl_version_string.find_last_not_of("0123456789.");
if (pos != std::string::npos && pos < gl_version_string.length() - 1) {
gpu_info->SetDriverInfo("", gl_version_string.substr(pos + 1));
return true;
}
return false;
} }
} // namespace gpu_info_collector } // namespace gpu_info_collector
...@@ -62,9 +62,9 @@ TEST_F(GPUInfoTest, DeviceIdD3D) { ...@@ -62,9 +62,9 @@ TEST_F(GPUInfoTest, DeviceIdD3D) {
TEST_F(GPUInfoTest, DriverVersionD3D) { TEST_F(GPUInfoTest, DriverVersionD3D) {
GPUInfo gpu_info; GPUInfo gpu_info;
ASSERT_TRUE(gpu_info_collector::CollectGraphicsInfoD3D(&d3d_, &gpu_info)); ASSERT_TRUE(gpu_info_collector::CollectGraphicsInfoD3D(&d3d_, &gpu_info));
std::wstring driver_version = gpu_info.driver_version(); std::string driver_version = gpu_info.driver_version();
EXPECT_FALSE(driver_version.empty()); EXPECT_FALSE(driver_version.empty());
EXPECT_EQ(driver_version, L"6.14.11.7715"); EXPECT_EQ(driver_version, "6.14.11.7715");
} }
TEST_F(GPUInfoTest, PixelShaderVersionD3D) { TEST_F(GPUInfoTest, PixelShaderVersionD3D) {
......
...@@ -237,6 +237,7 @@ ...@@ -237,6 +237,7 @@
'command_buffer_client', 'command_buffer_client',
'command_buffer_common', 'command_buffer_common',
'command_buffer_service', 'command_buffer_service',
'gpu_unittest_utils',
'gles2_lib', 'gles2_lib',
'gles2_implementation', 'gles2_implementation',
'gles2_cmd_helper', 'gles2_cmd_helper',
...@@ -250,8 +251,6 @@ ...@@ -250,8 +251,6 @@
'command_buffer/common/bitfield_helpers_test.cc', 'command_buffer/common/bitfield_helpers_test.cc',
'command_buffer/common/command_buffer_mock.cc', 'command_buffer/common/command_buffer_mock.cc',
'command_buffer/common/command_buffer_mock.h', 'command_buffer/common/command_buffer_mock.h',
'command_buffer/common/gl_mock.h',
'command_buffer/common/gl_mock.cc',
'command_buffer/common/gles2_cmd_format_test.cc', 'command_buffer/common/gles2_cmd_format_test.cc',
'command_buffer/common/gles2_cmd_format_test_autogen.h', 'command_buffer/common/gles2_cmd_format_test_autogen.h',
'command_buffer/common/gles2_cmd_id_test.cc', 'command_buffer/common/gles2_cmd_id_test.cc',
...@@ -293,6 +292,22 @@ ...@@ -293,6 +292,22 @@
'command_buffer/service/texture_manager_unittest.cc', 'command_buffer/service/texture_manager_unittest.cc',
], ],
}, },
{
'target_name': 'gpu_unittest_utils',
'type': 'static_library',
'dependencies': [
'../app/app.gyp:app_base',
'../testing/gmock.gyp:gmock',
'../testing/gtest.gyp:gtest',
],
'include_dirs': [
'..',
],
'sources': [
'command_buffer/common/gl_mock.h',
'command_buffer/common/gl_mock.cc',
],
},
{ {
'target_name': 'gles2_demo_lib', 'target_name': 'gles2_demo_lib',
'type': 'static_library', 'type': 'static_library',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment