1 // Copyright 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/run_loop.h" 7 #include "content/browser/gpu/browser_gpu_channel_host_factory.h" 8 #include "content/browser/gpu/gpu_process_host_ui_shim.h" 9 #include "content/common/gpu/client/context_provider_command_buffer.h" 10 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" 11 #include "content/common/gpu/gpu_process_launch_causes.h" 12 #include "content/public/browser/gpu_data_manager.h" 13 #include "content/public/common/content_switches.h" 14 #include "content/public/test/content_browser_test.h" 15 #include "ui/gl/gl_switches.h" 16 #include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h" 17 18 namespace { 19 20 using content::WebGraphicsContext3DCommandBufferImpl; 21 22 const content::CauseForGpuLaunch kInitCause = 23 content:: 24 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE; 25 26 class ContextTestBase : public content::ContentBrowserTest { 27 public: 28 virtual void SetUpOnMainThread() OVERRIDE { 29 if (!content::BrowserGpuChannelHostFactory::CanUseForTesting()) 30 return; 31 32 if (!content::BrowserGpuChannelHostFactory::instance()) 33 content::BrowserGpuChannelHostFactory::Initialize(true); 34 35 content::BrowserGpuChannelHostFactory* factory = 36 content::BrowserGpuChannelHostFactory::instance(); 37 CHECK(factory); 38 bool lose_context_when_out_of_memory = false; 39 scoped_refptr<content::GpuChannelHost> gpu_channel_host( 40 factory->EstablishGpuChannelSync(kInitCause)); 41 context_.reset( 42 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext( 43 gpu_channel_host.get(), 44 blink::WebGraphicsContext3D::Attributes(), 45 lose_context_when_out_of_memory, 46 GURL(), 47 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(), 48 NULL)); 49 CHECK(context_.get()); 50 context_->makeContextCurrent(); 51 context_support_ = context_->GetContextSupport(); 52 ContentBrowserTest::SetUpOnMainThread(); 53 } 54 55 virtual void TearDownOnMainThread() OVERRIDE { 56 // Must delete the context first. 57 context_.reset(NULL); 58 ContentBrowserTest::TearDownOnMainThread(); 59 } 60 61 protected: 62 scoped_ptr<content::WebGraphicsContext3DCommandBufferImpl> context_; 63 gpu::ContextSupport* context_support_; 64 }; 65 66 } // namespace 67 68 // Include the shared tests. 69 #define CONTEXT_TEST_F IN_PROC_BROWSER_TEST_F 70 #include "content/common/gpu/client/gpu_context_tests.h" 71 72 namespace content { 73 74 class BrowserGpuChannelHostFactoryTest : public ContentBrowserTest { 75 public: 76 virtual void SetUpOnMainThread() OVERRIDE { 77 if (!BrowserGpuChannelHostFactory::CanUseForTesting()) 78 return; 79 80 // Start all tests without a gpu channel so that the tests exercise a 81 // consistent codepath. 82 if (!BrowserGpuChannelHostFactory::instance()) 83 BrowserGpuChannelHostFactory::Initialize(false); 84 85 CHECK(GetFactory()); 86 87 ContentBrowserTest::SetUpOnMainThread(); 88 } 89 90 void OnContextLost(const base::Closure callback, int* counter) { 91 (*counter)++; 92 callback.Run(); 93 } 94 95 protected: 96 BrowserGpuChannelHostFactory* GetFactory() { 97 return BrowserGpuChannelHostFactory::instance(); 98 } 99 100 bool IsChannelEstablished() { 101 return GetFactory()->GetGpuChannel() != NULL; 102 } 103 104 void EstablishAndWait() { 105 base::RunLoop run_loop; 106 GetFactory()->EstablishGpuChannel(kInitCause, run_loop.QuitClosure()); 107 run_loop.Run(); 108 } 109 110 GpuChannelHost* GetGpuChannel() { 111 return GetFactory()->GetGpuChannel(); 112 } 113 114 static void Signal(bool *event) { 115 CHECK_EQ(*event, false); 116 *event = true; 117 } 118 119 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> CreateContext() { 120 bool lose_context_when_out_of_memory = false; 121 return make_scoped_ptr( 122 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext( 123 GetGpuChannel(), 124 blink::WebGraphicsContext3D::Attributes(), 125 lose_context_when_out_of_memory, 126 GURL(), 127 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(), 128 NULL)); 129 } 130 }; 131 132 // Fails since UI Compositor establishes a GpuChannel. 133 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, DISABLED_Basic) { 134 DCHECK(!IsChannelEstablished()); 135 EstablishAndWait(); 136 EXPECT_TRUE(GetGpuChannel() != NULL); 137 } 138 139 // Fails since UI Compositor establishes a GpuChannel. 140 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, 141 DISABLED_EstablishAndTerminate) { 142 DCHECK(!IsChannelEstablished()); 143 base::RunLoop run_loop; 144 GetFactory()->EstablishGpuChannel(kInitCause, run_loop.QuitClosure()); 145 GetFactory()->Terminate(); 146 147 // The callback should still trigger. 148 run_loop.Run(); 149 } 150 151 // Fails since UI Compositor establishes a GpuChannel. 152 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, 153 DISABLED_AlreadyEstablished) { 154 DCHECK(!IsChannelEstablished()); 155 scoped_refptr<GpuChannelHost> gpu_channel = 156 GetFactory()->EstablishGpuChannelSync(kInitCause); 157 158 // Expect established callback immediately. 159 bool event = false; 160 GetFactory()->EstablishGpuChannel( 161 kInitCause, 162 base::Bind(&BrowserGpuChannelHostFactoryTest::Signal, &event)); 163 EXPECT_TRUE(event); 164 EXPECT_EQ(gpu_channel, GetGpuChannel()); 165 } 166 167 // Fails since UI Compositor establishes a GpuChannel. 168 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, 169 DISABLED_CrashAndRecover) { 170 DCHECK(!IsChannelEstablished()); 171 EstablishAndWait(); 172 scoped_refptr<GpuChannelHost> host = GetGpuChannel(); 173 174 scoped_refptr<ContextProviderCommandBuffer> provider = 175 ContextProviderCommandBuffer::Create(CreateContext(), 176 "BrowserGpuChannelHostFactoryTest"); 177 base::RunLoop run_loop; 178 int counter = 0; 179 provider->SetLostContextCallback( 180 base::Bind(&BrowserGpuChannelHostFactoryTest::OnContextLost, 181 base::Unretained(this), run_loop.QuitClosure(), &counter)); 182 EXPECT_TRUE(provider->BindToCurrentThread()); 183 GpuProcessHostUIShim* shim = 184 GpuProcessHostUIShim::FromID(GetFactory()->GpuProcessHostId()); 185 EXPECT_TRUE(shim != NULL); 186 shim->SimulateCrash(); 187 run_loop.Run(); 188 189 EXPECT_EQ(1, counter); 190 EXPECT_FALSE(IsChannelEstablished()); 191 EstablishAndWait(); 192 EXPECT_TRUE(IsChannelEstablished()); 193 } 194 195 } // namespace content 196