// 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/message_loop.h" #include "base/run_loop.h" #include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/public/browser/gpu_data_manager_observer.h" #include "content/public/common/gpu_info.h" #include "testing/gtest/include/gtest/gtest.h" namespace content { namespace { class TestObserver : public GpuDataManagerObserver { public: TestObserver() : gpu_info_updated_(false), video_memory_usage_stats_updated_(false) { } virtual ~TestObserver() { } bool gpu_info_updated() const { return gpu_info_updated_; } bool video_memory_usage_stats_updated() const { return video_memory_usage_stats_updated_; } virtual void OnGpuInfoUpdate() OVERRIDE { gpu_info_updated_ = true; } virtual void OnVideoMemoryUsageStatsUpdate( const GPUVideoMemoryUsageStats& stats) OVERRIDE { video_memory_usage_stats_updated_ = true; } private: bool gpu_info_updated_; bool video_memory_usage_stats_updated_; }; } // namespace anonymous class GpuDataManagerImplTest : public testing::Test { public: GpuDataManagerImplTest() { } virtual ~GpuDataManagerImplTest() { } protected: void SetUp() { } void TearDown() { } MessageLoop message_loop_; }; // We use new method instead of GetInstance() method because we want // each test to be independent of each other. TEST_F(GpuDataManagerImplTest, GpuSideBlacklisting) { // If a feature is allowed in preliminary step (browser side), but // disabled when GPU process launches and collects full GPU info, // it's too late to let renderer know, so we basically block all GPU // access, to be on the safe side. GpuDataManagerImpl* manager = new GpuDataManagerImpl(); ASSERT_TRUE(manager); EXPECT_EQ(0, manager->GetBlacklistedFeatures()); EXPECT_TRUE(manager->GpuAccessAllowed()); const std::string blacklist_json = "{\n" " \"name\": \"gpu blacklist\",\n" " \"version\": \"0.1\",\n" " \"entries\": [\n" " {\n" " \"id\": 1,\n" " \"blacklist\": [\n" " \"webgl\"\n" " ]\n" " },\n" " {\n" " \"id\": 2,\n" " \"gl_renderer\": {\n" " \"op\": \"contains\",\n" " \"value\": \"GeForce\"\n" " },\n" " \"blacklist\": [\n" " \"accelerated_2d_canvas\"\n" " ]\n" " }\n" " ]\n" "}"; GPUInfo gpu_info; gpu_info.gpu.vendor_id = 0x10de; gpu_info.gpu.device_id = 0x0640; manager->InitializeForTesting(blacklist_json, gpu_info); EXPECT_TRUE(manager->GpuAccessAllowed()); EXPECT_EQ(GPU_FEATURE_TYPE_WEBGL, manager->GetBlacklistedFeatures()); gpu_info.gl_renderer = "NVIDIA GeForce GT 120"; manager->UpdateGpuInfo(gpu_info); EXPECT_FALSE(manager->GpuAccessAllowed()); EXPECT_EQ(GPU_FEATURE_TYPE_WEBGL | GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS, manager->GetBlacklistedFeatures()); delete manager; } TEST_F(GpuDataManagerImplTest, GpuSideExceptions) { GpuDataManagerImpl* manager = new GpuDataManagerImpl(); ASSERT_TRUE(manager); EXPECT_EQ(0, manager->GetBlacklistedFeatures()); EXPECT_TRUE(manager->GpuAccessAllowed()); const std::string blacklist_json = "{\n" " \"name\": \"gpu blacklist\",\n" " \"version\": \"0.1\",\n" " \"entries\": [\n" " {\n" " \"id\": 1,\n" " \"exceptions\": [\n" " {\n" " \"gl_renderer\": {\n" " \"op\": \"contains\",\n" " \"value\": \"GeForce\"\n" " }\n" " }\n" " ],\n" " \"blacklist\": [\n" " \"webgl\"\n" " ]\n" " }\n" " ]\n" "}"; GPUInfo gpu_info; gpu_info.gpu.vendor_id = 0x10de; gpu_info.gpu.device_id = 0x0640; manager->InitializeForTesting(blacklist_json, gpu_info); EXPECT_TRUE(manager->GpuAccessAllowed()); EXPECT_EQ(0, manager->GetBlacklistedFeatures()); // Now assue gpu process launches and full GPU info is collected. gpu_info.gl_renderer = "NVIDIA GeForce GT 120"; manager->UpdateGpuInfo(gpu_info); EXPECT_TRUE(manager->GpuAccessAllowed()); EXPECT_EQ(0, manager->GetBlacklistedFeatures()); delete manager; } TEST_F(GpuDataManagerImplTest, BlacklistCard) { GpuDataManagerImpl* manager = new GpuDataManagerImpl(); ASSERT_TRUE(manager); EXPECT_EQ(0, manager->GetBlacklistedFeatures()); EXPECT_TRUE(manager->GpuAccessAllowed()); manager->BlacklistCard(); EXPECT_FALSE(manager->GpuAccessAllowed()); EXPECT_EQ(GPU_FEATURE_TYPE_ALL, manager->GetBlacklistedFeatures()); delete manager; } TEST_F(GpuDataManagerImplTest, SoftwareRendering) { // Blacklist, then register SwiftShader. GpuDataManagerImpl* manager = new GpuDataManagerImpl(); ASSERT_TRUE(manager); EXPECT_EQ(0, manager->GetBlacklistedFeatures()); EXPECT_TRUE(manager->GpuAccessAllowed()); EXPECT_FALSE(manager->ShouldUseSoftwareRendering()); manager->BlacklistCard(); EXPECT_FALSE(manager->GpuAccessAllowed()); EXPECT_FALSE(manager->ShouldUseSoftwareRendering()); // If software rendering is enabled, even if we blacklist GPU, // GPU process is still allowed. const FilePath test_path(FILE_PATH_LITERAL("AnyPath")); manager->RegisterSwiftShaderPath(test_path); EXPECT_TRUE(manager->ShouldUseSoftwareRendering()); EXPECT_TRUE(manager->GpuAccessAllowed()); EXPECT_EQ(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS, manager->GetBlacklistedFeatures()); delete manager; } TEST_F(GpuDataManagerImplTest, SoftwareRendering2) { // Register SwiftShader, then blacklist. GpuDataManagerImpl* manager = new GpuDataManagerImpl(); ASSERT_TRUE(manager); EXPECT_EQ(0, manager->GetBlacklistedFeatures()); EXPECT_TRUE(manager->GpuAccessAllowed()); EXPECT_FALSE(manager->ShouldUseSoftwareRendering()); const FilePath test_path(FILE_PATH_LITERAL("AnyPath")); manager->RegisterSwiftShaderPath(test_path); EXPECT_EQ(0, manager->GetBlacklistedFeatures()); EXPECT_TRUE(manager->GpuAccessAllowed()); EXPECT_FALSE(manager->ShouldUseSoftwareRendering()); manager->BlacklistCard(); EXPECT_TRUE(manager->GpuAccessAllowed()); EXPECT_TRUE(manager->ShouldUseSoftwareRendering()); EXPECT_EQ(GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS, manager->GetBlacklistedFeatures()); delete manager; } TEST_F(GpuDataManagerImplTest, GpuInfoUpdate) { GpuDataManagerImpl* manager = new GpuDataManagerImpl(); ASSERT_TRUE(manager); TestObserver observer; manager->AddObserver(&observer); EXPECT_FALSE(observer.gpu_info_updated()); GPUInfo gpu_info; manager->UpdateGpuInfo(gpu_info); base::RunLoop run_loop; run_loop.RunUntilIdle(); EXPECT_TRUE(observer.gpu_info_updated()); delete manager; } TEST_F(GpuDataManagerImplTest, GPUVideoMemoryUsageStatsUpdate) { GpuDataManagerImpl* manager = new GpuDataManagerImpl(); ASSERT_TRUE(manager); TestObserver observer; manager->AddObserver(&observer); EXPECT_FALSE(observer.video_memory_usage_stats_updated()); GPUVideoMemoryUsageStats vram_stats; manager->UpdateVideoMemoryUsageStats(vram_stats); base::RunLoop run_loop; run_loop.RunUntilIdle(); EXPECT_TRUE(observer.video_memory_usage_stats_updated()); delete manager; } } // namespace content