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