1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/command_line.h" 6#include "base/message_loop/message_loop.h" 7#include "base/run_loop.h" 8#include "base/time/time.h" 9#include "content/browser/gpu/gpu_data_manager_impl_private.h" 10#include "content/public/browser/gpu_data_manager_observer.h" 11#include "gpu/command_buffer/service/gpu_switches.h" 12#include "gpu/config/gpu_feature_type.h" 13#include "gpu/config/gpu_info.h" 14#include "testing/gtest/include/gtest/gtest.h" 15#include "url/gurl.h" 16 17#if defined(OS_WIN) 18#include "base/win/windows_version.h" 19#endif 20 21#define LONG_STRING_CONST(...) #__VA_ARGS__ 22 23namespace content { 24namespace { 25 26class TestObserver : public GpuDataManagerObserver { 27 public: 28 TestObserver() 29 : gpu_info_updated_(false), 30 video_memory_usage_stats_updated_(false) { 31 } 32 virtual ~TestObserver() { } 33 34 bool gpu_info_updated() const { return gpu_info_updated_; } 35 bool video_memory_usage_stats_updated() const { 36 return video_memory_usage_stats_updated_; 37 } 38 39 virtual void OnGpuInfoUpdate() OVERRIDE { 40 gpu_info_updated_ = true; 41 } 42 43 virtual void OnVideoMemoryUsageStatsUpdate( 44 const GPUVideoMemoryUsageStats& stats) OVERRIDE { 45 video_memory_usage_stats_updated_ = true; 46 } 47 48 void Reset() { 49 gpu_info_updated_ = false; 50 video_memory_usage_stats_updated_ = false; 51 } 52 53 private: 54 bool gpu_info_updated_; 55 bool video_memory_usage_stats_updated_; 56}; 57 58static base::Time GetTimeForTesting() { 59 return base::Time::FromDoubleT(1000); 60} 61 62static GURL GetDomain1ForTesting() { 63 return GURL("http://foo.com/"); 64} 65 66static GURL GetDomain2ForTesting() { 67 return GURL("http://bar.com/"); 68} 69 70} // namespace anonymous 71 72class GpuDataManagerImplPrivateTest : public testing::Test { 73 public: 74 GpuDataManagerImplPrivateTest() { } 75 76 virtual ~GpuDataManagerImplPrivateTest() { } 77 78 protected: 79 // scoped_ptr doesn't work with GpuDataManagerImpl because its 80 // destructor is private. GpuDataManagerImplPrivateTest is however a friend 81 // so we can make a little helper class here. 82 class ScopedGpuDataManagerImpl { 83 public: 84 ScopedGpuDataManagerImpl() : impl_(new GpuDataManagerImpl()) { 85 EXPECT_TRUE(impl_); 86 EXPECT_TRUE(impl_->private_.get()); 87 } 88 ~ScopedGpuDataManagerImpl() { delete impl_; } 89 90 GpuDataManagerImpl* get() const { return impl_; } 91 92 GpuDataManagerImpl* operator->() const { return impl_; } 93 94 private: 95 GpuDataManagerImpl* impl_; 96 DISALLOW_COPY_AND_ASSIGN(ScopedGpuDataManagerImpl); 97 }; 98 99 // We want to test the code path where GpuDataManagerImplPrivate is created 100 // in the GpuDataManagerImpl constructor. 101 class ScopedGpuDataManagerImplPrivate { 102 public: 103 ScopedGpuDataManagerImplPrivate() : impl_(new GpuDataManagerImpl()) { 104 EXPECT_TRUE(impl_); 105 EXPECT_TRUE(impl_->private_.get()); 106 } 107 ~ScopedGpuDataManagerImplPrivate() { delete impl_; } 108 109 GpuDataManagerImplPrivate* get() const { 110 return impl_->private_.get(); 111 } 112 113 GpuDataManagerImplPrivate* operator->() const { 114 return impl_->private_.get(); 115 } 116 117 private: 118 GpuDataManagerImpl* impl_; 119 DISALLOW_COPY_AND_ASSIGN(ScopedGpuDataManagerImplPrivate); 120 }; 121 122 virtual void SetUp() { 123 } 124 125 virtual void TearDown() { 126 } 127 128 base::Time JustBeforeExpiration(const GpuDataManagerImplPrivate* manager); 129 base::Time JustAfterExpiration(const GpuDataManagerImplPrivate* manager); 130 void TestBlockingDomainFrom3DAPIs( 131 GpuDataManagerImpl::DomainGuilt guilt_level); 132 void TestUnblockingDomainFrom3DAPIs( 133 GpuDataManagerImpl::DomainGuilt guilt_level); 134 135 base::MessageLoop message_loop_; 136}; 137 138// We use new method instead of GetInstance() method because we want 139// each test to be independent of each other. 140 141TEST_F(GpuDataManagerImplPrivateTest, GpuSideBlacklisting) { 142 // If a feature is allowed in preliminary step (browser side), but 143 // disabled when GPU process launches and collects full GPU info, 144 // it's too late to let renderer know, so we basically block all GPU 145 // access, to be on the safe side. 146 ScopedGpuDataManagerImplPrivate manager; 147 EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount()); 148 std::string reason; 149 EXPECT_TRUE(manager->GpuAccessAllowed(&reason)); 150 EXPECT_TRUE(reason.empty()); 151 152 const std::string blacklist_json = LONG_STRING_CONST( 153 { 154 "name": "gpu blacklist", 155 "version": "0.1", 156 "entries": [ 157 { 158 "id": 1, 159 "features": [ 160 "webgl" 161 ] 162 }, 163 { 164 "id": 2, 165 "gl_renderer": ".*GeForce.*", 166 "features": [ 167 "accelerated_2d_canvas" 168 ] 169 } 170 ] 171 } 172 ); 173 174 gpu::GPUInfo gpu_info; 175 gpu_info.gpu.vendor_id = 0x10de; 176 gpu_info.gpu.device_id = 0x0640; 177 manager->InitializeForTesting(blacklist_json, gpu_info); 178 179 EXPECT_TRUE(manager->GpuAccessAllowed(&reason)); 180 EXPECT_TRUE(reason.empty()); 181 EXPECT_EQ(1u, manager->GetBlacklistedFeatureCount()); 182 EXPECT_TRUE(manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL)); 183 184 gpu_info.gl_vendor = "NVIDIA"; 185 gpu_info.gl_renderer = "NVIDIA GeForce GT 120"; 186 manager->UpdateGpuInfo(gpu_info); 187 EXPECT_FALSE(manager->GpuAccessAllowed(&reason)); 188 EXPECT_FALSE(reason.empty()); 189 EXPECT_EQ(2u, manager->GetBlacklistedFeatureCount()); 190 EXPECT_TRUE(manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL)); 191 EXPECT_TRUE(manager->IsFeatureBlacklisted( 192 gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)); 193} 194 195TEST_F(GpuDataManagerImplPrivateTest, GpuSideExceptions) { 196 ScopedGpuDataManagerImplPrivate manager; 197 EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount()); 198 EXPECT_TRUE(manager->GpuAccessAllowed(NULL)); 199 200 const std::string blacklist_json = LONG_STRING_CONST( 201 { 202 "name": "gpu blacklist", 203 "version": "0.1", 204 "entries": [ 205 { 206 "id": 1, 207 "exceptions": [ 208 { 209 "gl_renderer": ".*GeForce.*" 210 } 211 ], 212 "features": [ 213 "webgl" 214 ] 215 } 216 ] 217 } 218 ); 219 gpu::GPUInfo gpu_info; 220 gpu_info.gpu.vendor_id = 0x10de; 221 gpu_info.gpu.device_id = 0x0640; 222 manager->InitializeForTesting(blacklist_json, gpu_info); 223 224 EXPECT_TRUE(manager->GpuAccessAllowed(NULL)); 225 EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount()); 226 227 // Now assume gpu process launches and full GPU info is collected. 228 gpu_info.gl_renderer = "NVIDIA GeForce GT 120"; 229 manager->UpdateGpuInfo(gpu_info); 230 EXPECT_TRUE(manager->GpuAccessAllowed(NULL)); 231 EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount()); 232} 233 234TEST_F(GpuDataManagerImplPrivateTest, DisableHardwareAcceleration) { 235 ScopedGpuDataManagerImplPrivate manager; 236 EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount()); 237 std::string reason; 238 EXPECT_TRUE(manager->GpuAccessAllowed(&reason)); 239 EXPECT_TRUE(reason.empty()); 240 241 manager->DisableHardwareAcceleration(); 242 EXPECT_FALSE(manager->GpuAccessAllowed(&reason)); 243 EXPECT_FALSE(reason.empty()); 244 EXPECT_EQ(static_cast<size_t>(gpu::NUMBER_OF_GPU_FEATURE_TYPES), 245 manager->GetBlacklistedFeatureCount()); 246} 247 248TEST_F(GpuDataManagerImplPrivateTest, SwiftShaderRendering) { 249 // Blacklist, then register SwiftShader. 250 ScopedGpuDataManagerImplPrivate manager; 251 EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount()); 252 EXPECT_TRUE(manager->GpuAccessAllowed(NULL)); 253 EXPECT_FALSE(manager->ShouldUseSwiftShader()); 254 255 manager->DisableHardwareAcceleration(); 256 EXPECT_FALSE(manager->GpuAccessAllowed(NULL)); 257 EXPECT_FALSE(manager->ShouldUseSwiftShader()); 258 259 // If SwiftShader is enabled, even if we blacklist GPU, 260 // GPU process is still allowed. 261 const base::FilePath test_path(FILE_PATH_LITERAL("AnyPath")); 262 manager->RegisterSwiftShaderPath(test_path); 263 EXPECT_TRUE(manager->ShouldUseSwiftShader()); 264 EXPECT_TRUE(manager->GpuAccessAllowed(NULL)); 265 EXPECT_EQ(1u, manager->GetBlacklistedFeatureCount()); 266 EXPECT_TRUE(manager->IsFeatureBlacklisted( 267 gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)); 268} 269 270TEST_F(GpuDataManagerImplPrivateTest, SwiftShaderRendering2) { 271 // Register SwiftShader, then blacklist. 272 ScopedGpuDataManagerImplPrivate manager; 273 EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount()); 274 EXPECT_TRUE(manager->GpuAccessAllowed(NULL)); 275 EXPECT_FALSE(manager->ShouldUseSwiftShader()); 276 277 const base::FilePath test_path(FILE_PATH_LITERAL("AnyPath")); 278 manager->RegisterSwiftShaderPath(test_path); 279 EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount()); 280 EXPECT_TRUE(manager->GpuAccessAllowed(NULL)); 281 EXPECT_FALSE(manager->ShouldUseSwiftShader()); 282 283 manager->DisableHardwareAcceleration(); 284 EXPECT_TRUE(manager->GpuAccessAllowed(NULL)); 285 EXPECT_TRUE(manager->ShouldUseSwiftShader()); 286 EXPECT_EQ(1u, manager->GetBlacklistedFeatureCount()); 287 EXPECT_TRUE(manager->IsFeatureBlacklisted( 288 gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)); 289} 290 291TEST_F(GpuDataManagerImplPrivateTest, WarpEnabledOverridesSwiftShader) { 292 // If WARP fallback is enabled on Windows 8 it should not allow SwiftShader 293 // to be enabled. 294#if defined(OS_WIN) 295 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { 296 ScopedGpuDataManagerImplPrivate manager; 297 manager->ForceWarpModeForTesting(); 298 const base::FilePath test_path(FILE_PATH_LITERAL("AnyPath")); 299 manager->RegisterSwiftShaderPath(test_path); 300 manager->DisableHardwareAcceleration(); 301 EXPECT_TRUE(manager->ShouldUseWarp()); 302 EXPECT_FALSE(manager->ShouldUseSwiftShader()); 303 } 304#endif 305} 306 307TEST_F(GpuDataManagerImplPrivateTest, GpuInfoUpdate) { 308 ScopedGpuDataManagerImpl manager; 309 310 TestObserver observer; 311 manager->AddObserver(&observer); 312 313 { 314 base::RunLoop run_loop; 315 run_loop.RunUntilIdle(); 316 } 317 EXPECT_FALSE(observer.gpu_info_updated()); 318 319 gpu::GPUInfo gpu_info; 320 manager->UpdateGpuInfo(gpu_info); 321 { 322 base::RunLoop run_loop; 323 run_loop.RunUntilIdle(); 324 } 325 EXPECT_TRUE(observer.gpu_info_updated()); 326} 327 328TEST_F(GpuDataManagerImplPrivateTest, NoGpuInfoUpdateWithSwiftShader) { 329 ScopedGpuDataManagerImpl manager; 330 331 manager->DisableHardwareAcceleration(); 332 const base::FilePath test_path(FILE_PATH_LITERAL("AnyPath")); 333 manager->RegisterSwiftShaderPath(test_path); 334 EXPECT_TRUE(manager->ShouldUseSwiftShader()); 335 EXPECT_TRUE(manager->GpuAccessAllowed(NULL)); 336 337 { 338 base::RunLoop run_loop; 339 run_loop.RunUntilIdle(); 340 } 341 342 TestObserver observer; 343 manager->AddObserver(&observer); 344 { 345 base::RunLoop run_loop; 346 run_loop.RunUntilIdle(); 347 } 348 EXPECT_FALSE(observer.gpu_info_updated()); 349 350 gpu::GPUInfo gpu_info; 351 manager->UpdateGpuInfo(gpu_info); 352 { 353 base::RunLoop run_loop; 354 run_loop.RunUntilIdle(); 355 } 356 EXPECT_FALSE(observer.gpu_info_updated()); 357} 358 359TEST_F(GpuDataManagerImplPrivateTest, GPUVideoMemoryUsageStatsUpdate) { 360 ScopedGpuDataManagerImpl manager; 361 362 TestObserver observer; 363 manager->AddObserver(&observer); 364 365 { 366 base::RunLoop run_loop; 367 run_loop.RunUntilIdle(); 368 } 369 EXPECT_FALSE(observer.video_memory_usage_stats_updated()); 370 371 GPUVideoMemoryUsageStats vram_stats; 372 manager->UpdateVideoMemoryUsageStats(vram_stats); 373 { 374 base::RunLoop run_loop; 375 run_loop.RunUntilIdle(); 376 } 377 EXPECT_TRUE(observer.video_memory_usage_stats_updated()); 378} 379 380base::Time GpuDataManagerImplPrivateTest::JustBeforeExpiration( 381 const GpuDataManagerImplPrivate* manager) { 382 return GetTimeForTesting() + base::TimeDelta::FromMilliseconds( 383 manager->GetBlockAllDomainsDurationInMs()) - 384 base::TimeDelta::FromMilliseconds(3); 385} 386 387base::Time GpuDataManagerImplPrivateTest::JustAfterExpiration( 388 const GpuDataManagerImplPrivate* manager) { 389 return GetTimeForTesting() + base::TimeDelta::FromMilliseconds( 390 manager->GetBlockAllDomainsDurationInMs()) + 391 base::TimeDelta::FromMilliseconds(3); 392} 393 394void GpuDataManagerImplPrivateTest::TestBlockingDomainFrom3DAPIs( 395 GpuDataManagerImpl::DomainGuilt guilt_level) { 396 ScopedGpuDataManagerImplPrivate manager; 397 398 manager->BlockDomainFrom3DAPIsAtTime(GetDomain1ForTesting(), 399 guilt_level, 400 GetTimeForTesting()); 401 402 // This domain should be blocked no matter what. 403 EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_BLOCKED, 404 manager->Are3DAPIsBlockedAtTime(GetDomain1ForTesting(), 405 GetTimeForTesting())); 406 EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_BLOCKED, 407 manager->Are3DAPIsBlockedAtTime( 408 GetDomain1ForTesting(), JustBeforeExpiration(manager.get()))); 409 EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_BLOCKED, 410 manager->Are3DAPIsBlockedAtTime( 411 GetDomain1ForTesting(), JustAfterExpiration(manager.get()))); 412} 413 414void GpuDataManagerImplPrivateTest::TestUnblockingDomainFrom3DAPIs( 415 GpuDataManagerImpl::DomainGuilt guilt_level) { 416 ScopedGpuDataManagerImplPrivate manager; 417 418 manager->BlockDomainFrom3DAPIsAtTime(GetDomain1ForTesting(), 419 guilt_level, 420 GetTimeForTesting()); 421 422 // Unblocking the domain should work. 423 manager->UnblockDomainFrom3DAPIs(GetDomain1ForTesting()); 424 EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED, 425 manager->Are3DAPIsBlockedAtTime(GetDomain1ForTesting(), 426 GetTimeForTesting())); 427 EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED, 428 manager->Are3DAPIsBlockedAtTime( 429 GetDomain1ForTesting(), JustBeforeExpiration(manager.get()))); 430 EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED, 431 manager->Are3DAPIsBlockedAtTime( 432 GetDomain1ForTesting(), JustAfterExpiration(manager.get()))); 433} 434 435TEST_F(GpuDataManagerImplPrivateTest, BlockGuiltyDomainFrom3DAPIs) { 436 TestBlockingDomainFrom3DAPIs(GpuDataManagerImpl::DOMAIN_GUILT_KNOWN); 437} 438 439TEST_F(GpuDataManagerImplPrivateTest, BlockDomainOfUnknownGuiltFrom3DAPIs) { 440 TestBlockingDomainFrom3DAPIs(GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN); 441} 442 443TEST_F(GpuDataManagerImplPrivateTest, BlockAllDomainsFrom3DAPIs) { 444 ScopedGpuDataManagerImplPrivate manager; 445 446 manager->BlockDomainFrom3DAPIsAtTime(GetDomain1ForTesting(), 447 GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN, 448 GetTimeForTesting()); 449 450 // Blocking of other domains should expire. 451 EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_ALL_DOMAINS_BLOCKED, 452 manager->Are3DAPIsBlockedAtTime( 453 GetDomain2ForTesting(), JustBeforeExpiration(manager.get()))); 454 EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED, 455 manager->Are3DAPIsBlockedAtTime( 456 GetDomain2ForTesting(), JustAfterExpiration(manager.get()))); 457} 458 459TEST_F(GpuDataManagerImplPrivateTest, UnblockGuiltyDomainFrom3DAPIs) { 460 TestUnblockingDomainFrom3DAPIs(GpuDataManagerImpl::DOMAIN_GUILT_KNOWN); 461} 462 463TEST_F(GpuDataManagerImplPrivateTest, UnblockDomainOfUnknownGuiltFrom3DAPIs) { 464 TestUnblockingDomainFrom3DAPIs(GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN); 465} 466 467TEST_F(GpuDataManagerImplPrivateTest, UnblockOtherDomainFrom3DAPIs) { 468 ScopedGpuDataManagerImplPrivate manager; 469 470 manager->BlockDomainFrom3DAPIsAtTime(GetDomain1ForTesting(), 471 GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN, 472 GetTimeForTesting()); 473 474 manager->UnblockDomainFrom3DAPIs(GetDomain2ForTesting()); 475 476 EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED, 477 manager->Are3DAPIsBlockedAtTime( 478 GetDomain2ForTesting(), JustBeforeExpiration(manager.get()))); 479 480 // The original domain should still be blocked. 481 EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_BLOCKED, 482 manager->Are3DAPIsBlockedAtTime( 483 GetDomain1ForTesting(), JustBeforeExpiration(manager.get()))); 484} 485 486TEST_F(GpuDataManagerImplPrivateTest, UnblockThisDomainFrom3DAPIs) { 487 ScopedGpuDataManagerImplPrivate manager; 488 489 manager->BlockDomainFrom3DAPIsAtTime(GetDomain1ForTesting(), 490 GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN, 491 GetTimeForTesting()); 492 493 manager->UnblockDomainFrom3DAPIs(GetDomain1ForTesting()); 494 495 // This behavior is debatable. Perhaps the GPU reset caused by 496 // domain 1 should still cause other domains to be blocked. 497 EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED, 498 manager->Are3DAPIsBlockedAtTime( 499 GetDomain2ForTesting(), JustBeforeExpiration(manager.get()))); 500} 501 502#if defined(OS_LINUX) 503TEST_F(GpuDataManagerImplPrivateTest, SetGLStrings) { 504 const char* kGLVendorMesa = "Tungsten Graphics, Inc"; 505 const char* kGLRendererMesa = "Mesa DRI Intel(R) G41"; 506 const char* kGLVersionMesa801 = "2.1 Mesa 8.0.1-DEVEL"; 507 508 ScopedGpuDataManagerImplPrivate manager; 509 EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount()); 510 EXPECT_TRUE(manager->GpuAccessAllowed(NULL)); 511 512 const std::string blacklist_json = LONG_STRING_CONST( 513 { 514 "name": "gpu blacklist", 515 "version": "0.1", 516 "entries": [ 517 { 518 "id": 1, 519 "vendor_id": "0x8086", 520 "exceptions": [ 521 { 522 "device_id": ["0x0042"], 523 "driver_version": { 524 "op": ">=", 525 "value": "8.0.2" 526 } 527 } 528 ], 529 "features": [ 530 "webgl" 531 ] 532 } 533 ] 534 } 535 ); 536 gpu::GPUInfo gpu_info; 537 gpu_info.gpu.vendor_id = 0x8086; 538 gpu_info.gpu.device_id = 0x0042; 539 manager->InitializeForTesting(blacklist_json, gpu_info); 540 541 // Not enough GPUInfo. 542 EXPECT_TRUE(manager->GpuAccessAllowed(NULL)); 543 EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount()); 544 545 // Now assume browser gets GL strings from local state. 546 // The entry applies, blacklist more features than from the preliminary step. 547 // However, GPU process is not blocked because this is all browser side and 548 // happens before renderer launching. 549 manager->SetGLStrings(kGLVendorMesa, kGLRendererMesa, kGLVersionMesa801); 550 EXPECT_TRUE(manager->GpuAccessAllowed(NULL)); 551 EXPECT_EQ(1u, manager->GetBlacklistedFeatureCount()); 552 EXPECT_TRUE(manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL)); 553} 554 555TEST_F(GpuDataManagerImplPrivateTest, SetGLStringsNoEffects) { 556 const char* kGLVendorMesa = "Tungsten Graphics, Inc"; 557 const char* kGLRendererMesa = "Mesa DRI Intel(R) G41"; 558 const char* kGLVersionMesa801 = "2.1 Mesa 8.0.1-DEVEL"; 559 const char* kGLVersionMesa802 = "2.1 Mesa 8.0.2-DEVEL"; 560 561 ScopedGpuDataManagerImplPrivate manager; 562 EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount()); 563 EXPECT_TRUE(manager->GpuAccessAllowed(NULL)); 564 565 const std::string blacklist_json = LONG_STRING_CONST( 566 { 567 "name": "gpu blacklist", 568 "version": "0.1", 569 "entries": [ 570 { 571 "id": 1, 572 "vendor_id": "0x8086", 573 "exceptions": [ 574 { 575 "device_id": ["0x0042"], 576 "driver_version": { 577 "op": ">=", 578 "value": "8.0.2" 579 } 580 } 581 ], 582 "features": [ 583 "webgl" 584 ] 585 } 586 ] 587 } 588 ); 589 gpu::GPUInfo gpu_info; 590 gpu_info.gpu.vendor_id = 0x8086; 591 gpu_info.gpu.device_id = 0x0042; 592 gpu_info.gl_vendor = kGLVendorMesa; 593 gpu_info.gl_renderer = kGLRendererMesa; 594 gpu_info.gl_version = kGLVersionMesa801; 595 gpu_info.driver_vendor = "Mesa"; 596 gpu_info.driver_version = "8.0.1"; 597 manager->InitializeForTesting(blacklist_json, gpu_info); 598 599 // Full GPUInfo, the entry applies. 600 EXPECT_TRUE(manager->GpuAccessAllowed(NULL)); 601 EXPECT_EQ(1u, manager->GetBlacklistedFeatureCount()); 602 EXPECT_TRUE(manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL)); 603 604 // Now assume browser gets GL strings from local state. 605 // SetGLStrings() has no effects because GPUInfo already got these strings. 606 // (Otherwise the entry should not apply.) 607 manager->SetGLStrings(kGLVendorMesa, kGLRendererMesa, kGLVersionMesa802); 608 EXPECT_TRUE(manager->GpuAccessAllowed(NULL)); 609 EXPECT_EQ(1u, manager->GetBlacklistedFeatureCount()); 610 EXPECT_TRUE(manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL)); 611} 612#endif // OS_LINUX 613 614TEST_F(GpuDataManagerImplPrivateTest, GpuDriverBugListSingle) { 615 ScopedGpuDataManagerImplPrivate manager; 616 manager->gpu_driver_bugs_.insert(5); 617 618 base::CommandLine command_line(0, NULL); 619 manager->AppendGpuCommandLine(&command_line); 620 621 EXPECT_TRUE(command_line.HasSwitch(switches::kGpuDriverBugWorkarounds)); 622 std::string args = command_line.GetSwitchValueASCII( 623 switches::kGpuDriverBugWorkarounds); 624 EXPECT_STREQ("5", args.c_str()); 625} 626 627TEST_F(GpuDataManagerImplPrivateTest, GpuDriverBugListMultiple) { 628 ScopedGpuDataManagerImplPrivate manager; 629 manager->gpu_driver_bugs_.insert(5); 630 manager->gpu_driver_bugs_.insert(7); 631 632 base::CommandLine command_line(0, NULL); 633 manager->AppendGpuCommandLine(&command_line); 634 635 EXPECT_TRUE(command_line.HasSwitch(switches::kGpuDriverBugWorkarounds)); 636 std::string args = command_line.GetSwitchValueASCII( 637 switches::kGpuDriverBugWorkarounds); 638 EXPECT_STREQ("5,7", args.c_str()); 639} 640 641TEST_F(GpuDataManagerImplPrivateTest, BlacklistAllFeatures) { 642 ScopedGpuDataManagerImplPrivate manager; 643 EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount()); 644 std::string reason; 645 EXPECT_TRUE(manager->GpuAccessAllowed(&reason)); 646 EXPECT_TRUE(reason.empty()); 647 648 const std::string blacklist_json = LONG_STRING_CONST( 649 { 650 "name": "gpu blacklist", 651 "version": "0.1", 652 "entries": [ 653 { 654 "id": 1, 655 "features": [ 656 "all" 657 ] 658 } 659 ] 660 } 661 ); 662 663 gpu::GPUInfo gpu_info; 664 gpu_info.gpu.vendor_id = 0x10de; 665 gpu_info.gpu.device_id = 0x0640; 666 manager->InitializeForTesting(blacklist_json, gpu_info); 667 668 EXPECT_EQ(static_cast<size_t>(gpu::NUMBER_OF_GPU_FEATURE_TYPES), 669 manager->GetBlacklistedFeatureCount()); 670 // TODO(zmo): remove the Linux specific behavior once we fix 671 // crbug.com/238466. 672#if defined(OS_LINUX) 673 EXPECT_TRUE(manager->GpuAccessAllowed(&reason)); 674 EXPECT_TRUE(reason.empty()); 675#else 676 EXPECT_FALSE(manager->GpuAccessAllowed(&reason)); 677 EXPECT_FALSE(reason.empty()); 678#endif 679} 680 681TEST_F(GpuDataManagerImplPrivateTest, UpdateActiveGpu) { 682 ScopedGpuDataManagerImpl manager; 683 684 const std::string blacklist_json = LONG_STRING_CONST( 685 { 686 "name": "gpu blacklist", 687 "version": "0.1", 688 "entries": [ 689 { 690 "id": 1, 691 "vendor_id": "0x8086", 692 "multi_gpu_category": "active", 693 "features": [ 694 "webgl" 695 ] 696 } 697 ] 698 } 699 ); 700 701 // Two GPUs, the secondary Intel GPU is active. 702 gpu::GPUInfo gpu_info; 703 gpu_info.gpu.vendor_id = 0x10de; 704 gpu_info.gpu.device_id = 0x0640; 705 gpu_info.gpu.active = false; 706 gpu::GPUInfo::GPUDevice intel_gpu; 707 intel_gpu.vendor_id = 0x8086; 708 intel_gpu.device_id = 0x04a1; 709 intel_gpu.active = true; 710 gpu_info.secondary_gpus.push_back(intel_gpu); 711 712 manager->InitializeForTesting(blacklist_json, gpu_info); 713 TestObserver observer; 714 manager->AddObserver(&observer); 715 716 EXPECT_EQ(1u, manager->GetBlacklistedFeatureCount()); 717 718 // Update with the same Intel GPU active. 719 EXPECT_FALSE(manager->UpdateActiveGpu(0x8086, 0x04a1)); 720 { 721 base::RunLoop run_loop; 722 run_loop.RunUntilIdle(); 723 } 724 EXPECT_FALSE(observer.gpu_info_updated()); 725 EXPECT_EQ(1u, manager->GetBlacklistedFeatureCount()); 726 727 // Set NVIDIA GPU to be active. 728 EXPECT_TRUE(manager->UpdateActiveGpu(0x10de, 0x0640)); 729 { 730 base::RunLoop run_loop; 731 run_loop.RunUntilIdle(); 732 } 733 EXPECT_TRUE(observer.gpu_info_updated()); 734 EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount()); 735 736 observer.Reset(); 737 EXPECT_FALSE(observer.gpu_info_updated()); 738 739 // Update with the same NVIDIA GPU active. 740 EXPECT_FALSE(manager->UpdateActiveGpu(0x10de, 0x0640)); 741 { 742 base::RunLoop run_loop; 743 run_loop.RunUntilIdle(); 744 } 745 EXPECT_FALSE(observer.gpu_info_updated()); 746 EXPECT_EQ(0u, manager->GetBlacklistedFeatureCount()); 747 748 // Set Intel GPU to be active. 749 EXPECT_TRUE(manager->UpdateActiveGpu(0x8086, 0x04a1)); 750 { 751 base::RunLoop run_loop; 752 run_loop.RunUntilIdle(); 753 } 754 EXPECT_TRUE(observer.gpu_info_updated()); 755 EXPECT_EQ(1u, manager->GetBlacklistedFeatureCount()); 756} 757 758} // namespace content 759