Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / gpu / gpu_data_manager_impl_private_unittest.cc
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
23 namespace content {
24 namespace {
25
26 class 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
58 static base::Time GetTimeForTesting() {
59   return base::Time::FromDoubleT(1000);
60 }
61
62 static GURL GetDomain1ForTesting() {
63   return GURL("http://foo.com/");
64 }
65
66 static GURL GetDomain2ForTesting() {
67   return GURL("http://bar.com/");
68 }
69
70 }  // namespace anonymous
71
72 class 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
141 TEST_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
195 TEST_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
234 TEST_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
248 TEST_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
270 TEST_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
291 TEST_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
307 TEST_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
328 TEST_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
359 TEST_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
380 base::Time GpuDataManagerImplPrivateTest::JustBeforeExpiration(
381     const GpuDataManagerImplPrivate* manager) {
382   return GetTimeForTesting() + base::TimeDelta::FromMilliseconds(
383       manager->GetBlockAllDomainsDurationInMs()) -
384       base::TimeDelta::FromMilliseconds(3);
385 }
386
387 base::Time GpuDataManagerImplPrivateTest::JustAfterExpiration(
388     const GpuDataManagerImplPrivate* manager) {
389   return GetTimeForTesting() + base::TimeDelta::FromMilliseconds(
390       manager->GetBlockAllDomainsDurationInMs()) +
391       base::TimeDelta::FromMilliseconds(3);
392 }
393
394 void 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
414 void 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
435 TEST_F(GpuDataManagerImplPrivateTest, BlockGuiltyDomainFrom3DAPIs) {
436   TestBlockingDomainFrom3DAPIs(GpuDataManagerImpl::DOMAIN_GUILT_KNOWN);
437 }
438
439 TEST_F(GpuDataManagerImplPrivateTest, BlockDomainOfUnknownGuiltFrom3DAPIs) {
440   TestBlockingDomainFrom3DAPIs(GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN);
441 }
442
443 TEST_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
459 TEST_F(GpuDataManagerImplPrivateTest, UnblockGuiltyDomainFrom3DAPIs) {
460   TestUnblockingDomainFrom3DAPIs(GpuDataManagerImpl::DOMAIN_GUILT_KNOWN);
461 }
462
463 TEST_F(GpuDataManagerImplPrivateTest, UnblockDomainOfUnknownGuiltFrom3DAPIs) {
464   TestUnblockingDomainFrom3DAPIs(GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN);
465 }
466
467 TEST_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
486 TEST_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)
503 TEST_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
555 TEST_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
614 TEST_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
627 TEST_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
641 TEST_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
681 TEST_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