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.
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"
20 using content::WebGraphicsContext3DCommandBufferImpl;
22 const content::CauseForGpuLaunch kInitCause =
24 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
26 class ContextTestBase : public content::ContentBrowserTest {
28 virtual void SetUpOnMainThread() OVERRIDE {
29 if (!content::BrowserGpuChannelHostFactory::CanUseForTesting())
32 if (!content::BrowserGpuChannelHostFactory::instance())
33 content::BrowserGpuChannelHostFactory::Initialize(true);
35 content::BrowserGpuChannelHostFactory* factory =
36 content::BrowserGpuChannelHostFactory::instance();
38 scoped_refptr<content::GpuChannelHost> gpu_channel_host(
39 factory->EstablishGpuChannelSync(kInitCause));
41 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
42 gpu_channel_host.get(),
43 blink::WebGraphicsContext3D::Attributes(),
45 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
47 CHECK(context_.get());
48 context_->makeContextCurrent();
49 context_support_ = context_->GetContextSupport();
50 ContentBrowserTest::SetUpOnMainThread();
53 virtual void TearDownOnMainThread() OVERRIDE {
54 // Must delete the context first.
56 ContentBrowserTest::TearDownOnMainThread();
60 scoped_ptr<content::WebGraphicsContext3DCommandBufferImpl> context_;
61 gpu::ContextSupport* context_support_;
66 // Include the shared tests.
67 #define CONTEXT_TEST_F IN_PROC_BROWSER_TEST_F
68 #include "content/common/gpu/client/gpu_context_tests.h"
72 class BrowserGpuChannelHostFactoryTest : public ContextTestBase {
74 virtual void SetUpOnMainThread() OVERRIDE {
75 if (!BrowserGpuChannelHostFactory::CanUseForTesting())
78 // Start all tests without a gpu channel so that the tests exercise a
79 // consistent codepath.
80 if (!BrowserGpuChannelHostFactory::instance())
81 BrowserGpuChannelHostFactory::Initialize(false);
85 ContentBrowserTest::SetUpOnMainThread();
88 virtual void TearDownOnMainThread() OVERRIDE {
89 ContextTestBase::TearDownOnMainThread();
92 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
93 // Start all tests without a gpu channel so that the tests exercise a
94 // consistent codepath.
95 command_line->AppendSwitch(switches::kDisableGpuProcessPrelaunch);
98 void OnContextLost(const base::Closure callback, int* counter) {
104 BrowserGpuChannelHostFactory* GetFactory() {
105 return BrowserGpuChannelHostFactory::instance();
108 bool IsChannelEstablished() {
109 return GetFactory()->GetGpuChannel() != NULL;
112 void EstablishAndWait() {
113 base::RunLoop run_loop;
114 GetFactory()->EstablishGpuChannel(kInitCause, run_loop.QuitClosure());
118 GpuChannelHost* GetGpuChannel() {
119 return GetFactory()->GetGpuChannel();
122 static void Signal(bool *event) {
123 CHECK_EQ(*event, false);
127 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> CreateContext() {
128 return make_scoped_ptr(
129 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
131 blink::WebGraphicsContext3D::Attributes(),
133 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
138 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, Basic) {
142 DCHECK(!IsChannelEstablished());
144 EXPECT_TRUE(GetGpuChannel() != NULL);
147 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest,
148 EstablishAndTerminate) {
152 DCHECK(!IsChannelEstablished());
153 base::RunLoop run_loop;
154 GetFactory()->EstablishGpuChannel(kInitCause, run_loop.QuitClosure());
155 GetFactory()->Terminate();
157 // The callback should still trigger.
161 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, AlreadyEstablished) {
165 DCHECK(!IsChannelEstablished());
166 scoped_refptr<GpuChannelHost> gpu_channel =
167 GetFactory()->EstablishGpuChannelSync(kInitCause);
169 // Expect established callback immediately.
171 GetFactory()->EstablishGpuChannel(
173 base::Bind(&BrowserGpuChannelHostFactoryTest::Signal, &event));
175 EXPECT_EQ(gpu_channel, GetGpuChannel());
178 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, CrashAndRecover) {
182 DCHECK(!IsChannelEstablished());
184 scoped_refptr<GpuChannelHost> host = GetGpuChannel();
186 scoped_refptr<ContextProviderCommandBuffer> provider =
187 ContextProviderCommandBuffer::Create(CreateContext(),
188 "BrowserGpuChannelHostFactoryTest");
189 base::RunLoop run_loop;
191 provider->SetLostContextCallback(
192 base::Bind(&BrowserGpuChannelHostFactoryTest::OnContextLost,
193 base::Unretained(this), run_loop.QuitClosure(), &counter));
194 EXPECT_TRUE(provider->BindToCurrentThread());
195 GpuProcessHostUIShim* shim =
196 GpuProcessHostUIShim::FromID(GetFactory()->GpuProcessHostId());
197 EXPECT_TRUE(shim != NULL);
198 shim->SimulateCrash();
201 EXPECT_EQ(1, counter);
202 EXPECT_FALSE(IsChannelEstablished());
204 EXPECT_TRUE(IsChannelEstablished());
207 } // namespace content