diff options
author | zmo@chromium.org <zmo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-15 00:45:40 +0000 |
---|---|---|
committer | zmo@chromium.org <zmo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-15 00:45:40 +0000 |
commit | c86e7a815b8a8b8af67bba66561be1aef1e399a3 (patch) | |
tree | 8a97853864d4bd16b89a722d9c9f989fe89db83d /content | |
parent | 9028a0e4a2ebdafc4bc7bc67dd3c44b231dadf3c (diff) | |
download | chromium_src-c86e7a815b8a8b8af67bba66561be1aef1e399a3.zip chromium_src-c86e7a815b8a8b8af67bba66561be1aef1e399a3.tar.gz chromium_src-c86e7a815b8a8b8af67bba66561be1aef1e399a3.tar.bz2 |
Only collect GL/D3D context specific GPUInfo in GPU process
Instead of collecting full GPUInfo. Basic GPUInfo are already collected at Browser process startup time.
This avoids sandbox issue with libpci on linux. Also, it makes GPU startup faster.
BUG=162928,165374
TEST=manual about:gpu
TBR=joi
Review URL: https://codereview.chromium.org/11574049
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@173248 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/gpu/gpu_data_manager_impl.cc | 11 | ||||
-rw-r--r-- | content/content_tests.gypi | 1 | ||||
-rw-r--r-- | content/gpu/gpu_child_thread.cc | 10 | ||||
-rw-r--r-- | content/gpu/gpu_info_collector.cc | 48 | ||||
-rw-r--r-- | content/gpu/gpu_info_collector.h | 57 | ||||
-rw-r--r-- | content/gpu/gpu_info_collector_android.cc | 13 | ||||
-rw-r--r-- | content/gpu/gpu_info_collector_linux.cc | 142 | ||||
-rw-r--r-- | content/gpu/gpu_info_collector_mac.mm | 14 | ||||
-rw-r--r-- | content/gpu/gpu_info_collector_unittest_win.cc | 56 | ||||
-rw-r--r-- | content/gpu/gpu_info_collector_win.cc | 260 | ||||
-rw-r--r-- | content/gpu/gpu_main.cc | 12 | ||||
-rw-r--r-- | content/public/common/content_switches.cc | 3 | ||||
-rw-r--r-- | content/public/common/content_switches.h | 1 | ||||
-rw-r--r-- | content/test/gpu/gpu_test_config.cc | 2 |
14 files changed, 283 insertions, 347 deletions
diff --git a/content/browser/gpu/gpu_data_manager_impl.cc b/content/browser/gpu/gpu_data_manager_impl.cc index b015bb8..27590e7 100644 --- a/content/browser/gpu/gpu_data_manager_impl.cc +++ b/content/browser/gpu/gpu_data_manager_impl.cc @@ -132,7 +132,7 @@ void GpuDataManagerImpl::Initialize() { return; GPUInfo gpu_info; - gpu_info_collector::CollectPreliminaryGraphicsInfo(&gpu_info); + gpu_info_collector::CollectBasicGraphicsInfo(&gpu_info); #if defined(ARCH_CPU_X86_FAMILY) if (!gpu_info.gpu.vendor_id || !gpu_info.gpu.device_id) gpu_info.finalized = true; @@ -190,7 +190,11 @@ void GpuDataManagerImpl::RequestCompleteGpuInfoIfNeeded() { complete_gpu_info_already_requested_ = true; GpuProcessHost::SendOnIO( +#if defined(OS_WIN) GpuProcessHost::GPU_PROCESS_KIND_UNSANDBOXED, +#else + GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, +#endif CAUSE_FOR_GPU_LAUNCH_GPUDATAMANAGER_REQUESTCOMPLETEGPUINFOIFNEEDED, new GpuMsg_CollectGraphicsInfo()); } @@ -224,7 +228,7 @@ void GpuDataManagerImpl::UpdateGpuInfo(const GPUInfo& gpu_info) { { base::AutoLock auto_lock(gpu_info_lock_); - gpu_info_ = gpu_info; + gpu_info_collector::MergeGPUInfo(&gpu_info_, gpu_info); complete_gpu_info_already_requested_ = complete_gpu_info_already_requested_ || gpu_info_.finalized; } @@ -470,9 +474,6 @@ void GpuDataManagerImpl::AppendGpuCommandLine( command_line->AppendSwitchASCII(switches::kSupportsDualGpus, "false"); } - if (!gpu_blacklist_.get() || !gpu_blacklist_->needs_more_info()) - command_line->AppendSwitch(switches::kSkipGpuFullInfoCollection); - if (!swiftshader_path.empty()) command_line->AppendSwitchPath(switches::kSwiftShaderPath, swiftshader_path); diff --git a/content/content_tests.gypi b/content/content_tests.gypi index fdac476..63f9038 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi @@ -358,7 +358,6 @@ 'common/sandbox_mac_system_access_unittest.mm', 'components/navigation_interception/intercept_navigation_resource_throttle_unittest.cc', 'gpu/gpu_info_collector_unittest.cc', - 'gpu/gpu_info_collector_unittest_win.cc', 'renderer/active_notification_tracker_unittest.cc', 'renderer/android/email_detector_unittest.cc', 'renderer/android/phone_number_detector_unittest.cc', diff --git a/content/gpu/gpu_child_thread.cc b/content/gpu/gpu_child_thread.cc index b3b787a..4e0816b 100644 --- a/content/gpu/gpu_child_thread.cc +++ b/content/gpu/gpu_child_thread.cc @@ -74,7 +74,6 @@ GpuChildThread::GpuChildThread(const std::string& channel_id) } } - GpuChildThread::~GpuChildThread() { logging::SetLogMessageHandler(NULL); } @@ -134,7 +133,6 @@ void GpuChildThread::OnInitialize() { // take a significant amount of time. gpu_info_.initialization_time = base::Time::Now() - process_start_time_; - // Defer creation of the render thread. This is to prevent it from handling // IPC messages before the sandbox has been enabled and all other necessary // initialization has succeeded. @@ -144,11 +142,9 @@ void GpuChildThread::OnInitialize() { ChildProcess::current()->io_message_loop_proxy(), ChildProcess::current()->GetShutDownEvent())); -#if defined(OS_LINUX) // Ensure the browser process receives the GPU info before a reply to any // subsequent IPC it might send. Send(new GpuHostMsg_GraphicsInfoCollected(gpu_info_)); -#endif } void GpuChildThread::StopWatchdog() { @@ -167,12 +163,8 @@ void GpuChildThread::OnCollectGraphicsInfo() { command_line->HasSwitch(switches::kInProcessGPU)); #endif // OS_WIN - // Sandbox state is not part of the gpu info collection. It is determined - // in GpuMain() and passed down to GpuChildThread. - bool sandboxed = gpu_info_.sandboxed; - if (!gpu_info_collector::CollectGraphicsInfo(&gpu_info_)) + if (!gpu_info_collector::CollectContextGraphicsInfo(&gpu_info_)) VLOG(1) << "gpu_info_collector::CollectGraphicsInfo failed"; - gpu_info_.sandboxed = sandboxed; GetContentClient()->SetGpuInfo(gpu_info_); #if defined(OS_WIN) diff --git a/content/gpu/gpu_info_collector.cc b/content/gpu/gpu_info_collector.cc index 14b1697..6d13b29 100644 --- a/content/gpu/gpu_info_collector.cc +++ b/content/gpu/gpu_info_collector.cc @@ -94,32 +94,44 @@ bool CollectGraphicsInfoGL(content::GPUInfo* gpu_info) { gpu_info->gl_renderer = GetGLString(GL_RENDERER); gpu_info->gl_vendor = GetGLString(GL_VENDOR); - gpu_info->gl_version_string =GetGLString(GL_VERSION); - gpu_info->gl_extensions =GetGLString(GL_EXTENSIONS); - - bool validGLVersionInfo = CollectGLVersionInfo(gpu_info); - bool validVideoCardInfo = CollectVideoCardInfo(gpu_info); - bool validDriverInfo = CollectDriverInfoGL(gpu_info); - + gpu_info->gl_extensions = GetGLString(GL_EXTENSIONS); + gpu_info->gl_version_string = GetGLString(GL_VERSION); + std::string glsl_version_string = GetGLString(GL_SHADING_LANGUAGE_VERSION); // TODO(kbr): remove once the destruction of a current context automatically // clears the current context. context->ReleaseCurrent(surface.get()); - return (validGLVersionInfo && validVideoCardInfo && validDriverInfo); -} - -bool CollectGLVersionInfo(content::GPUInfo* gpu_info) { - std::string gl_version_string = gpu_info->gl_version_string; - std::string glsl_version_string = - GetGLString(GL_SHADING_LANGUAGE_VERSION); - - gpu_info->gl_version = GetVersionFromString(gl_version_string); - + gpu_info->gl_version = GetVersionFromString(gpu_info->gl_version_string); std::string glsl_version = GetVersionFromString(glsl_version_string); gpu_info->pixel_shader_version = glsl_version; gpu_info->vertex_shader_version = glsl_version; - return true; + return CollectDriverInfoGL(gpu_info); +} + +void MergeGPUInfoGL(content::GPUInfo* basic_gpu_info, + const content::GPUInfo& context_gpu_info) { + DCHECK(basic_gpu_info); + basic_gpu_info->gl_renderer = context_gpu_info.gl_renderer; + basic_gpu_info->gl_vendor = context_gpu_info.gl_vendor; + basic_gpu_info->gl_version_string = context_gpu_info.gl_version_string; + basic_gpu_info->gl_extensions = context_gpu_info.gl_extensions; + basic_gpu_info->gl_version = context_gpu_info.gl_version; + basic_gpu_info->pixel_shader_version = + context_gpu_info.pixel_shader_version; + basic_gpu_info->vertex_shader_version = + context_gpu_info.vertex_shader_version; + + if (!context_gpu_info.driver_vendor.empty()) + basic_gpu_info->driver_vendor = context_gpu_info.driver_vendor; + if (!context_gpu_info.driver_version.empty()) + basic_gpu_info->driver_version = context_gpu_info.driver_version; + + basic_gpu_info->can_lose_context = context_gpu_info.can_lose_context; + basic_gpu_info->sandboxed = context_gpu_info.sandboxed; + basic_gpu_info->gpu_accessible = context_gpu_info.gpu_accessible; + basic_gpu_info->finalized = context_gpu_info.finalized; + basic_gpu_info->initialization_time = context_gpu_info.initialization_time; } } // namespace gpu_info_collector diff --git a/content/gpu/gpu_info_collector.h b/content/gpu/gpu_info_collector.h index 6a5fa43..1871d67 100644 --- a/content/gpu/gpu_info_collector.h +++ b/content/gpu/gpu_info_collector.h @@ -10,59 +10,40 @@ #include "content/common/content_export.h" #include "content/public/common/gpu_info.h" -struct IDirect3D9; - namespace gpu_info_collector { -// Populate variables with necessary graphics card information. -// Returns true on success. -bool CollectGraphicsInfo(content::GPUInfo* gpu_info); - -// Similar to CollectGraphicsInfo, only this collects a subset of variables -// without creating a GL/DirectX context (and without the danger of crashing). +// Collects basic GPU info without creating a GL/DirectX context (and without +// the danger of crashing), including vendor_id and device_id. +// This is called at browser process startup time. // The subset each platform collects may be different. -CONTENT_EXPORT bool CollectPreliminaryGraphicsInfo( +CONTENT_EXPORT bool CollectBasicGraphicsInfo( content::GPUInfo* gpu_info); -#if defined(OS_WIN) -// Windows provides two ways of doing graphics so we need two ways of -// collecting info based on what's on a user's machine. -// The selection between the two methods is done in the cc file. - -// A D3D argument is passed in for testing purposes -CONTENT_EXPORT bool CollectGraphicsInfoD3D(IDirect3D9* d3d, - content::GPUInfo* gpu_info); - -// Collects D3D driver version/date through registry lookup. -// Note that this does not require a D3D context. -// device_id here is the raw data in DISPLAY_DEVICE. -CONTENT_EXPORT bool CollectDriverInfoD3D(const std::wstring& device_id, - content::GPUInfo* gpu_info); +// Create a GL/DirectX context and collect related info. +// This is called at GPU process startup time. +// Returns true on success. +bool CollectContextGraphicsInfo(content::GPUInfo* gpu_info); +#if defined(OS_WIN) // Collect the DirectX Disagnostics information about the attached displays. bool GetDxDiagnostics(content::DxDiagNode* output); #endif // OS_WIN -// All platforms have a GL version for collecting information +// Create a GL context and collect GL strings and versions. CONTENT_EXPORT bool CollectGraphicsInfoGL(content::GPUInfo* gpu_info); -// Collect GL and Shading language version information -bool CollectGLVersionInfo(content::GPUInfo* gpu_info); - -// Platform specific method for collecting vendor and device ids -bool CollectVideoCardInfo(content::GPUInfo* gpu_info); - // Each platform stores the driver version on the GL_VERSION string differently bool CollectDriverInfoGL(content::GPUInfo* gpu_info); -// Advanced Micro Devices has interesting configurations on laptops were -// there are two videocards that can alternatively a given process output. -enum AMDVideoCardType { - UNKNOWN, - STANDALONE, - INTEGRATED, - SWITCHABLE -}; +// Merge GPUInfo from CollectContextGraphicsInfo into basic GPUInfo. +// This is platform specific, depending on which info are collected at which +// stage. +void MergeGPUInfo(content::GPUInfo* basic_gpu_info, + const content::GPUInfo& context_gpu_info); + +// MergeGPUInfo() when GL driver is used. +void MergeGPUInfoGL(content::GPUInfo* basic_gpu_info, + const content::GPUInfo& context_gpu_info); } // namespace gpu_info_collector diff --git a/content/gpu/gpu_info_collector_android.cc b/content/gpu/gpu_info_collector_android.cc index df0a7f2..20d29ce1 100644 --- a/content/gpu/gpu_info_collector_android.cc +++ b/content/gpu/gpu_info_collector_android.cc @@ -45,14 +45,14 @@ std::string GetDriverVersionFromString(const std::string& version_string) { namespace gpu_info_collector { -bool CollectGraphicsInfo(content::GPUInfo* gpu_info) { +bool CollectContextGraphicsInfo(content::GPUInfo* gpu_info) { // can_lose_context must be false to enable accelerated Canvas2D gpu_info->can_lose_context = false; gpu_info->finalized = true; return CollectGraphicsInfoGL(gpu_info); } -bool CollectPreliminaryGraphicsInfo(content::GPUInfo* gpu_info) { +bool CollectBasicGraphicsInfo(content::GPUInfo* gpu_info) { gpu_info->can_lose_context = false; // Create a short-lived context on the UI thread to collect the GL strings. if (!CollectGraphicsInfoGL(gpu_info)) @@ -73,14 +73,15 @@ bool CollectPreliminaryGraphicsInfo(content::GPUInfo* gpu_info) { return true; } -bool CollectVideoCardInfo(content::GPUInfo* gpu_info) { - return true; -} - bool CollectDriverInfoGL(content::GPUInfo* gpu_info) { gpu_info->driver_version = GetDriverVersionFromString( gpu_info->gl_version_string); return true; } +void MergeGPUInfo(content::GPUInfo* basic_gpu_info, + const content::GPUInfo& context_gpu_info) { + MergeGPUInfoGL(basic_gpu_info, context_gpu_info); +} + } // namespace gpu_info_collector diff --git a/content/gpu/gpu_info_collector_linux.cc b/content/gpu/gpu_info_collector_linux.cc index d849cab..e96d251 100644 --- a/content/gpu/gpu_info_collector_linux.cc +++ b/content/gpu/gpu_info_collector_linux.cc @@ -97,75 +97,7 @@ const uint32 kVendorIDIntel = 0x8086; const uint32 kVendorIDNVidia = 0x10de; const uint32 kVendorIDAMD = 0x1002; -} // namespace anonymous - -namespace gpu_info_collector { - -bool CollectGraphicsInfo(content::GPUInfo* gpu_info) { - DCHECK(gpu_info); - *gpu_info = content::GPUInfo(); - - TRACE_EVENT0("gpu", "gpu_info_collector::CollectGraphicsInfo"); - - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kGpuNoContextLost)) { - gpu_info->can_lose_context = false; - } else { -#if defined(OS_CHROMEOS) - gpu_info->can_lose_context = false; -#else - // 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->can_lose_context = - (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2); -#endif - } - - gpu_info->finalized = true; - bool rt = CollectGraphicsInfoGL(gpu_info); - - return rt; -} - -bool CollectPreliminaryGraphicsInfo(content::GPUInfo* gpu_info) { - DCHECK(gpu_info); - - bool rt = CollectVideoCardInfo(gpu_info); - - std::string driver_version; - switch (gpu_info->gpu.vendor_id) { - case kVendorIDAMD: - driver_version = CollectDriverVersionATI(); - if (!driver_version.empty()) { - gpu_info->driver_vendor = "ATI / AMD"; - gpu_info->driver_version = driver_version; - } - break; - case kVendorIDNVidia: - driver_version = CollectDriverVersionNVidia(); - if (!driver_version.empty()) { - gpu_info->driver_vendor = "NVIDIA"; - gpu_info->driver_version = driver_version; - } - break; - case kVendorIDIntel: - // In dual-GPU cases, sometimes PCI scan only gives us the - // integrated GPU (i.e., the Intel one). - driver_version = CollectDriverVersionNVidia(); - if (!driver_version.empty()) { - gpu_info->driver_vendor = "NVIDIA"; - gpu_info->driver_version = driver_version; - // Machines with more than two GPUs are not handled. - if (gpu_info->secondary_gpus.size() <= 1) - gpu_info->optimus = true; - } - break; - } - - return rt; -} - -bool CollectVideoCardInfo(content::GPUInfo* gpu_info) { +bool CollectPCIVideoCardInfo(content::GPUInfo* gpu_info) { DCHECK(gpu_info); if (IsPciSupported() == false) { @@ -256,6 +188,73 @@ bool CollectVideoCardInfo(content::GPUInfo* gpu_info) { return (primary_gpu_identified); } +} // namespace anonymous + +namespace gpu_info_collector { + +bool CollectContextGraphicsInfo(content::GPUInfo* gpu_info) { + DCHECK(gpu_info); + + TRACE_EVENT0("gpu", "gpu_info_collector::CollectGraphicsInfo"); + + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kGpuNoContextLost)) { + gpu_info->can_lose_context = false; + } else { +#if defined(OS_CHROMEOS) + gpu_info->can_lose_context = false; +#else + // 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->can_lose_context = + (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2); +#endif + } + + gpu_info->finalized = true; + bool rt = CollectGraphicsInfoGL(gpu_info); + + return rt; +} + +bool CollectBasicGraphicsInfo(content::GPUInfo* gpu_info) { + DCHECK(gpu_info); + + bool rt = CollectPCIVideoCardInfo(gpu_info); + + std::string driver_version; + switch (gpu_info->gpu.vendor_id) { + case kVendorIDAMD: + driver_version = CollectDriverVersionATI(); + if (!driver_version.empty()) { + gpu_info->driver_vendor = "ATI / AMD"; + gpu_info->driver_version = driver_version; + } + break; + case kVendorIDNVidia: + driver_version = CollectDriverVersionNVidia(); + if (!driver_version.empty()) { + gpu_info->driver_vendor = "NVIDIA"; + gpu_info->driver_version = driver_version; + } + break; + case kVendorIDIntel: + // In dual-GPU cases, sometimes PCI scan only gives us the + // integrated GPU (i.e., the Intel one). + driver_version = CollectDriverVersionNVidia(); + if (!driver_version.empty()) { + gpu_info->driver_vendor = "NVIDIA"; + gpu_info->driver_version = driver_version; + // Machines with more than two GPUs are not handled. + if (gpu_info->secondary_gpus.size() <= 1) + gpu_info->optimus = true; + } + break; + } + + return rt; +} + bool CollectDriverInfoGL(content::GPUInfo* gpu_info) { DCHECK(gpu_info); @@ -281,4 +280,9 @@ bool CollectDriverInfoGL(content::GPUInfo* gpu_info) { return true; } +void MergeGPUInfo(content::GPUInfo* basic_gpu_info, + const content::GPUInfo& context_gpu_info) { + MergeGPUInfoGL(basic_gpu_info, context_gpu_info); +} + } // namespace gpu_info_collector diff --git a/content/gpu/gpu_info_collector_mac.mm b/content/gpu/gpu_info_collector_mac.mm index f703f0f..66c362d 100644 --- a/content/gpu/gpu_info_collector_mac.mm +++ b/content/gpu/gpu_info_collector_mac.mm @@ -158,9 +158,8 @@ bool CollectPCIVideoCardInfo(content::GPUInfo* gpu_info) { namespace gpu_info_collector { -bool CollectGraphicsInfo(content::GPUInfo* gpu_info) { +bool CollectContextGraphicsInfo(content::GPUInfo* gpu_info) { DCHECK(gpu_info); - *gpu_info = content::GPUInfo(); TRACE_EVENT0("gpu", "gpu_info_collector::CollectGraphicsInfo"); @@ -170,7 +169,7 @@ bool CollectGraphicsInfo(content::GPUInfo* gpu_info) { return CollectGraphicsInfoGL(gpu_info); } -bool CollectPreliminaryGraphicsInfo(content::GPUInfo* gpu_info) { +bool CollectBasicGraphicsInfo(content::GPUInfo* gpu_info) { DCHECK(gpu_info); std::string model_name; @@ -184,10 +183,6 @@ bool CollectPreliminaryGraphicsInfo(content::GPUInfo* gpu_info) { return CollectPCIVideoCardInfo(gpu_info); } -bool CollectVideoCardInfo(content::GPUInfo* gpu_info) { - return CollectPreliminaryGraphicsInfo(gpu_info); -} - bool CollectDriverInfoGL(content::GPUInfo* gpu_info) { DCHECK(gpu_info); @@ -203,4 +198,9 @@ bool CollectDriverInfoGL(content::GPUInfo* gpu_info) { return true; } +void MergeGPUInfo(content::GPUInfo* basic_gpu_info, + const content::GPUInfo& context_gpu_info) { + MergeGPUInfoGL(basic_gpu_info, context_gpu_info); +} + } // namespace gpu_info_collector diff --git a/content/gpu/gpu_info_collector_unittest_win.cc b/content/gpu/gpu_info_collector_unittest_win.cc deleted file mode 100644 index 86e876e..0000000 --- a/content/gpu/gpu_info_collector_unittest_win.cc +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2012 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 "base/memory/scoped_ptr.h" -#include "content/gpu/gpu_idirect3d9_mock_win.h" -#include "content/gpu/gpu_info_collector.h" -#include "content/public/common/gpu_info.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using ::testing::_; -using ::testing::Return; -using ::testing::SetArgumentPointee; - -class GPUInfoTest : public testing::Test { - public: - GPUInfoTest() { } - virtual ~GPUInfoTest() { } - - protected: - void SetUp() { - // Test variables taken from Lenovo T61 - test_identifier_.VendorId = 0x10de; - test_identifier_.DeviceId = 0x429; - test_identifier_.DriverVersion.QuadPart = 0x6000e000b1e23; // 6.14.11.7715 - test_caps_.PixelShaderVersion = 0xffff0300; // 3.0 - test_caps_.VertexShaderVersion = 0xfffe0300; // 3.0 - - EXPECT_CALL(d3d_, GetDeviceCaps(_, _, _)) - .WillOnce(DoAll(SetArgumentPointee<2>(test_caps_), - Return(D3D_OK))); - EXPECT_CALL(d3d_, QueryInterface(__uuidof(IDirect3D9Ex), _)) - .WillOnce(Return(E_NOINTERFACE)); - } - void TearDown() { - } - - public: - IDirect3D9Mock d3d_; - private: - D3DADAPTER_IDENTIFIER9 test_identifier_; - D3DCAPS9 test_caps_; -}; - -TEST_F(GPUInfoTest, PixelShaderVersionD3D) { - content::GPUInfo gpu_info; - ASSERT_TRUE(gpu_info_collector::CollectGraphicsInfoD3D(&d3d_, &gpu_info)); - EXPECT_EQ(gpu_info.pixel_shader_version, "3.0"); -} - -TEST_F(GPUInfoTest, VertexShaderVersionD3D) { - content::GPUInfo gpu_info; - ASSERT_TRUE(gpu_info_collector::CollectGraphicsInfoD3D(&d3d_, &gpu_info)); - EXPECT_EQ(gpu_info.vertex_shader_version, "3.0"); -} diff --git a/content/gpu/gpu_info_collector_win.cc b/content/gpu/gpu_info_collector_win.cc index ed326aa..bc95048 100644 --- a/content/gpu/gpu_info_collector_win.cc +++ b/content/gpu/gpu_info_collector_win.cc @@ -157,9 +157,14 @@ content::GpuPerformanceStats RetrieveGpuPerformanceStatsWithHistograms() { return stats; } -} // namespace anonymous - -namespace gpu_info_collector { +// Advanced Micro Devices has interesting configurations on laptops were +// there are two videocards that can alternatively a given process output. +enum AMDVideoCardType { + UNKNOWN, + STANDALONE, + INTEGRATED, + SWITCHABLE +}; #if !defined(GOOGLE_CHROME_BUILD) AMDVideoCardType GetAMDVideocardType() { @@ -171,13 +176,94 @@ AMDVideoCardType GetAMDVideocardType() { AMDVideoCardType GetAMDVideocardType(); #endif -bool CollectGraphicsInfo(content::GPUInfo* gpu_info) { +bool CollectDriverInfoD3D(const std::wstring& device_id, + content::GPUInfo* gpu_info) { + TRACE_EVENT0("gpu", "CollectDriverInfoD3D"); + + // create device info for the display device + HDEVINFO device_info = SetupDiGetClassDevsW( + NULL, device_id.c_str(), NULL, + DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES); + if (device_info == INVALID_HANDLE_VALUE) { + LOG(ERROR) << "Creating device info failed"; + return false; + } + + DWORD index = 0; + bool found = false; + SP_DEVINFO_DATA device_info_data; + device_info_data.cbSize = sizeof(device_info_data); + while (SetupDiEnumDeviceInfo(device_info, index++, &device_info_data)) { + WCHAR value[255]; + if (SetupDiGetDeviceRegistryPropertyW(device_info, + &device_info_data, + SPDRP_DRIVER, + NULL, + reinterpret_cast<PBYTE>(value), + sizeof(value), + NULL)) { + HKEY key; + std::wstring driver_key = L"System\\CurrentControlSet\\Control\\Class\\"; + driver_key += value; + LONG result = RegOpenKeyExW( + HKEY_LOCAL_MACHINE, driver_key.c_str(), 0, KEY_QUERY_VALUE, &key); + if (result == ERROR_SUCCESS) { + DWORD dwcb_data = sizeof(value); + std::string driver_version; + result = RegQueryValueExW( + key, L"DriverVersion", NULL, NULL, + reinterpret_cast<LPBYTE>(value), &dwcb_data); + if (result == ERROR_SUCCESS) + driver_version = WideToASCII(std::wstring(value)); + + std::string driver_date; + dwcb_data = sizeof(value); + result = RegQueryValueExW( + key, L"DriverDate", NULL, NULL, + reinterpret_cast<LPBYTE>(value), &dwcb_data); + if (result == ERROR_SUCCESS) + driver_date = WideToASCII(std::wstring(value)); + + std::string driver_vendor; + dwcb_data = sizeof(value); + result = RegQueryValueExW( + key, L"ProviderName", NULL, NULL, + reinterpret_cast<LPBYTE>(value), &dwcb_data); + if (result == ERROR_SUCCESS) { + driver_vendor = WideToASCII(std::wstring(value)); + if (driver_vendor == "Advanced Micro Devices, Inc." || + driver_vendor == "ATI Technologies Inc.") { + // We are conservative and assume that in the absence of a clear + // signal the videocard is assumed to be switchable. Additionally, + // some switchable systems with Intel GPUs aren't correctly + // detected, so always count them. + AMDVideoCardType amd_card_type = GetAMDVideocardType(); + gpu_info->amd_switchable = (gpu_info->gpu.vendor_id == 0x8086) || + (amd_card_type != STANDALONE); + } + } + + gpu_info->driver_vendor = driver_vendor; + gpu_info->driver_version = driver_version; + gpu_info->driver_date = driver_date; + found = true; + RegCloseKey(key); + break; + } + } + } + SetupDiDestroyDeviceInfoList(device_info); + return found; +} + +} // namespace anonymous + +namespace gpu_info_collector { + +bool CollectContextGraphicsInfo(content::GPUInfo* gpu_info) { TRACE_EVENT0("gpu", "CollectGraphicsInfo"); DCHECK(gpu_info); - *gpu_info = content::GPUInfo(); - - gpu_info->performance_stats = RetrieveGpuPerformanceStats(); if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL)) { std::string requested_implementation_name = @@ -215,35 +301,12 @@ bool CollectGraphicsInfo(content::GPUInfo* gpu_info) { return false; } - if (!CollectGraphicsInfoD3D(d3d, gpu_info)) - return false; - - // DirectX diagnostics are collected asynchronously because it takes a - // couple of seconds. Do not mark gpu_info as complete until that is done. - return true; -} - -bool CollectPreliminaryGraphicsInfo(content::GPUInfo* gpu_info) { - TRACE_EVENT0("gpu", "CollectPreliminaryGraphicsInfo"); - - DCHECK(gpu_info); - - bool rt = true; - if (!CollectVideoCardInfo(gpu_info)) - rt = false; - - gpu_info->performance_stats = RetrieveGpuPerformanceStatsWithHistograms(); - - return rt; -} - -bool CollectGraphicsInfoD3D(IDirect3D9* d3d, content::GPUInfo* gpu_info) { - TRACE_EVENT0("gpu", "CollectGraphicsInfoD3D"); - - DCHECK(d3d); - DCHECK(gpu_info); - - bool succeed = CollectVideoCardInfo(gpu_info); + // Get can_lose_context + base::win::ScopedComPtr<IDirect3D9Ex> d3dex; + if (SUCCEEDED(d3dex.QueryFrom(d3d))) + gpu_info->can_lose_context = false; + else + gpu_info->can_lose_context = true; // Get version information D3DCAPS9 d3d_caps; @@ -256,24 +319,21 @@ bool CollectGraphicsInfoD3D(IDirect3D9* d3d, content::GPUInfo* gpu_info) { VersionNumberToString(d3d_caps.VertexShaderVersion); } else { LOG(ERROR) << "d3d->GetDeviceCaps() failed"; - succeed = false; + return false; } - // Get can_lose_context - base::win::ScopedComPtr<IDirect3D9Ex> d3dex; - if (SUCCEEDED(d3dex.QueryFrom(d3d))) - gpu_info->can_lose_context = false; - else - gpu_info->can_lose_context = true; - + // DirectX diagnostics are collected asynchronously because it takes a + // couple of seconds. Do not mark gpu_info as complete until that is done. return true; } -bool CollectVideoCardInfo(content::GPUInfo* gpu_info) { - TRACE_EVENT0("gpu", "CollectVideoCardInfo"); +bool CollectBasicGraphicsInfo(content::GPUInfo* gpu_info) { + TRACE_EVENT0("gpu", "CollectPreliminaryGraphicsInfo"); DCHECK(gpu_info); + gpu_info->performance_stats = RetrieveGpuPerformanceStatsWithHistograms(); + // nvd3d9wrap.dll is loaded into all processes when Optimus is enabled. HMODULE nvd3d9wrap = GetModuleHandleW(L"nvd3d9wrap.dll"); gpu_info->optimus = nvd3d9wrap != NULL; @@ -304,86 +364,6 @@ bool CollectVideoCardInfo(content::GPUInfo* gpu_info) { return false; } -bool CollectDriverInfoD3D(const std::wstring& device_id, - content::GPUInfo* gpu_info) { - TRACE_EVENT0("gpu", "CollectDriverInfoD3D"); - - // create device info for the display device - HDEVINFO device_info = SetupDiGetClassDevsW( - NULL, device_id.c_str(), NULL, - DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES); - if (device_info == INVALID_HANDLE_VALUE) { - LOG(ERROR) << "Creating device info failed"; - return false; - } - - DWORD index = 0; - bool found = false; - SP_DEVINFO_DATA device_info_data; - device_info_data.cbSize = sizeof(device_info_data); - while (SetupDiEnumDeviceInfo(device_info, index++, &device_info_data)) { - WCHAR value[255]; - if (SetupDiGetDeviceRegistryPropertyW(device_info, - &device_info_data, - SPDRP_DRIVER, - NULL, - reinterpret_cast<PBYTE>(value), - sizeof(value), - NULL)) { - HKEY key; - std::wstring driver_key = L"System\\CurrentControlSet\\Control\\Class\\"; - driver_key += value; - LONG result = RegOpenKeyExW( - HKEY_LOCAL_MACHINE, driver_key.c_str(), 0, KEY_QUERY_VALUE, &key); - if (result == ERROR_SUCCESS) { - DWORD dwcb_data = sizeof(value); - std::string driver_version; - result = RegQueryValueExW( - key, L"DriverVersion", NULL, NULL, - reinterpret_cast<LPBYTE>(value), &dwcb_data); - if (result == ERROR_SUCCESS) - driver_version = WideToASCII(std::wstring(value)); - - std::string driver_date; - dwcb_data = sizeof(value); - result = RegQueryValueExW( - key, L"DriverDate", NULL, NULL, - reinterpret_cast<LPBYTE>(value), &dwcb_data); - if (result == ERROR_SUCCESS) - driver_date = WideToASCII(std::wstring(value)); - - std::string driver_vendor; - dwcb_data = sizeof(value); - result = RegQueryValueExW( - key, L"ProviderName", NULL, NULL, - reinterpret_cast<LPBYTE>(value), &dwcb_data); - if (result == ERROR_SUCCESS) { - driver_vendor = WideToASCII(std::wstring(value)); - if (driver_vendor == "Advanced Micro Devices, Inc." || - driver_vendor == "ATI Technologies Inc.") { - // We are conservative and assume that in the absence of a clear - // signal the videocard is assumed to be switchable. Additionally, - // some switchable systems with Intel GPUs aren't correctly - // detected, so always count them. - AMDVideoCardType amd_card_type = GetAMDVideocardType(); - gpu_info->amd_switchable = (gpu_info->gpu.vendor_id == 0x8086) || - (amd_card_type != STANDALONE); - } - } - - gpu_info->driver_vendor = driver_vendor; - gpu_info->driver_version = driver_version; - gpu_info->driver_date = driver_date; - found = true; - RegCloseKey(key); - break; - } - } - } - SetupDiDestroyDeviceInfoList(device_info); - return found; -} - bool CollectDriverInfoGL(content::GPUInfo* gpu_info) { TRACE_EVENT0("gpu", "CollectDriverInfoGL"); @@ -402,4 +382,32 @@ bool CollectDriverInfoGL(content::GPUInfo* gpu_info) { return false; } +void MergeGPUInfo(content::GPUInfo* basic_gpu_info, + const content::GPUInfo& context_gpu_info) { + DCHECK(basic_gpu_info); + + if (context_gpu_info.software_rendering) { + basic_gpu_info->software_rendering = true; + return; + } + + if (!context_gpu_info.gl_vendor.empty()) { + MergeGPUInfoGL(basic_gpu_info, context_gpu_info); + return; + } + + basic_gpu_info->pixel_shader_version = + context_gpu_info.pixel_shader_version; + basic_gpu_info->vertex_shader_version = + context_gpu_info.vertex_shader_version; + + basic_gpu_info->dx_diagnostics = context_gpu_info.dx_diagnostics; + + basic_gpu_info->can_lose_context = context_gpu_info.can_lose_context; + basic_gpu_info->sandboxed = context_gpu_info.sandboxed; + basic_gpu_info->gpu_accessible = context_gpu_info.gpu_accessible; + basic_gpu_info->finalized = context_gpu_info.finalized; + basic_gpu_info->initialization_time = context_gpu_info.initialization_time; +} + } // namespace gpu_info_collector diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc index 976072a..3020600 100644 --- a/content/gpu/gpu_main.cc +++ b/content/gpu/gpu_main.cc @@ -181,14 +181,12 @@ int GpuMain(const MainFunctionParams& parameters) { bool initialized_gl_context = false; // Load and initialize the GL implementation and locate the GL entry points. if (gfx::GLSurface::InitializeOneOff()) { - if (!command_line.HasSwitch(switches::kSkipGpuFullInfoCollection)) { - if (!gpu_info_collector::CollectGraphicsInfo(&gpu_info)) - VLOG(1) << "gpu_info_collector::CollectGraphicsInfo failed"; - GetContentClient()->SetGpuInfo(gpu_info); + if (!gpu_info_collector::CollectContextGraphicsInfo(&gpu_info)) + VLOG(1) << "gpu_info_collector::CollectGraphicsInfo failed"; + GetContentClient()->SetGpuInfo(gpu_info); - // We know that CollectGraphicsInfo will initialize a GLContext. - initialized_gl_context = true; - } + // We know that CollectGraphicsInfo will initialize a GLContext. + initialized_gl_context = true; #if defined(OS_LINUX) && !defined(OS_CHROMEOS) if (gpu_info.gpu.vendor_id == 0x10de && // NVIDIA diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 0b4f74c..cf0b4db 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc @@ -624,9 +624,6 @@ const char kSitePerProcess[] = "site-per-process"; // content. The switch is intended only for tests. const char kSkipGpuDataLoading[] = "skip-gpu-data-loading"; -// Skip collecting full GPU info upon GPU process launch. -const char kSkipGpuFullInfoCollection[] = "skip-gpu-full-info-collection"; - // GestureTapDown events are deferred by this many miillseconds before // sending them to the renderer. const char kTapDownDeferralTimeMs[] = "tap-down-deferral-time"; diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index a4e059f..bed0688 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h @@ -187,7 +187,6 @@ CONTENT_EXPORT extern const char kSimulateTouchScreenWithMouse[]; CONTENT_EXPORT extern const char kSingleProcess[]; CONTENT_EXPORT extern const char kSitePerProcess[]; CONTENT_EXPORT extern const char kSkipGpuDataLoading[]; -extern const char kSkipGpuFullInfoCollection[]; extern const char kTapDownDeferralTimeMs[]; CONTENT_EXPORT extern const char kTestSandbox[]; CONTENT_EXPORT extern const char kTestingFixedHttpPort[]; diff --git a/content/test/gpu/gpu_test_config.cc b/content/test/gpu/gpu_test_config.cc index 5c93336..00837ad 100644 --- a/content/test/gpu/gpu_test_config.cc +++ b/content/test/gpu/gpu_test_config.cc @@ -212,7 +212,7 @@ bool GPUTestBotConfig::LoadCurrentConfig(const content::GPUInfo* gpu_info) { bool rt; if (gpu_info == NULL) { content::GPUInfo my_gpu_info; - gpu_info_collector::CollectPreliminaryGraphicsInfo(&my_gpu_info); + gpu_info_collector::CollectBasicGraphicsInfo(&my_gpu_info); rt = SetGPUInfo(my_gpu_info); } else { rt = SetGPUInfo(*gpu_info); |