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/browser_thread.h"
13 #include "content/public/common/content_switches.h"
14 #include "content/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 class ContextTestBase : public content::ContentBrowserTest {
24 virtual void SetUpOnMainThread() OVERRIDE {
25 if (!content::BrowserGpuChannelHostFactory::instance())
26 content::BrowserGpuChannelHostFactory::Initialize(true);
28 content::BrowserGpuChannelHostFactory* factory =
29 content::BrowserGpuChannelHostFactory::instance();
31 scoped_refptr<content::GpuChannelHost> gpu_channel_host(
32 factory->EstablishGpuChannelSync(
34 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE));
36 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
37 gpu_channel_host.get(),
38 WebKit::WebGraphicsContext3D::Attributes(),
40 CHECK(context_.get());
41 context_->makeContextCurrent();
42 context_support_ = context_->GetContextSupport();
43 ContentBrowserTest::SetUpOnMainThread();
46 virtual void TearDownOnMainThread() OVERRIDE {
47 // Must delete the context first.
49 ContentBrowserTest::TearDownOnMainThread();
53 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context_;
54 gpu::ContextSupport* context_support_;
59 // Include the shared tests.
60 #define CONTEXT_TEST_F IN_PROC_BROWSER_TEST_F
61 #include "content/common/gpu/client/gpu_context_tests.h"
65 class BrowserGpuChannelHostFactoryTest : public ContextTestBase {
67 virtual void SetUpOnMainThread() OVERRIDE {
68 // Start all tests without a gpu channel so that the tests exercise a
69 // consistent codepath.
70 if (!content::BrowserGpuChannelHostFactory::instance())
71 content::BrowserGpuChannelHostFactory::Initialize(false);
75 ContentBrowserTest::SetUpOnMainThread();
78 virtual void TearDownOnMainThread() OVERRIDE {
79 ContextTestBase::TearDownOnMainThread();
82 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
83 // Start all tests without a gpu channel so that the tests exercise a
84 // consistent codepath.
85 command_line->AppendSwitch(switches::kDisableGpuProcessPrelaunch);
88 void OnContextLost(const base::Closure callback, int* counter) {
94 BrowserGpuChannelHostFactory* GetFactory() {
95 return BrowserGpuChannelHostFactory::instance();
98 bool IsChannelEstablished() {
99 return GetFactory()->GetGpuChannel() != NULL;
102 void EstablishAndWait() {
103 base::RunLoop run_loop;
104 GetFactory()->EstablishGpuChannel(
105 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE,
106 run_loop.QuitClosure());
110 GpuChannelHost* GetGpuChannel() {
111 return GetFactory()->GetGpuChannel();
114 static void Signal(bool *event) {
115 CHECK_EQ(*event, false);
119 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> CreateContext() {
120 return make_scoped_ptr(
121 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
123 WebKit::WebGraphicsContext3D::Attributes(),
128 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, Basic) {
129 DCHECK(!IsChannelEstablished());
131 EXPECT_TRUE(GetGpuChannel() != NULL);
134 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest,
135 EstablishAndTerminate) {
136 DCHECK(!IsChannelEstablished());
137 base::RunLoop run_loop;
138 GetFactory()->EstablishGpuChannel(
139 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE,
140 run_loop.QuitClosure());
141 GetFactory()->Terminate();
143 // The callback should still trigger.
147 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, AlreadyEstablished) {
148 DCHECK(!IsChannelEstablished());
149 scoped_refptr<GpuChannelHost> gpu_channel =
150 GetFactory()->EstablishGpuChannelSync(
151 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE);
153 // Expect established callback immediately.
155 GetFactory()->EstablishGpuChannel(
156 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE,
157 base::Bind(&BrowserGpuChannelHostFactoryTest::Signal, &event));
159 EXPECT_EQ(gpu_channel, GetGpuChannel());
162 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, CrashAndRecover) {
163 DCHECK(!IsChannelEstablished());
165 scoped_refptr<GpuChannelHost> host = GetGpuChannel();
167 scoped_refptr<ContextProviderCommandBuffer> provider =
168 ContextProviderCommandBuffer::Create(CreateContext(),
169 "BrowserGpuChannelHostFactoryTest");
170 base::RunLoop run_loop;
172 provider->SetLostContextCallback(
173 base::Bind(&BrowserGpuChannelHostFactoryTest::OnContextLost,
174 base::Unretained(this), run_loop.QuitClosure(), &counter));
175 EXPECT_TRUE(provider->BindToCurrentThread());
176 GpuProcessHostUIShim* shim =
177 GpuProcessHostUIShim::FromID(GetFactory()->GpuProcessHostId());
178 EXPECT_TRUE(shim != NULL);
179 shim->SimulateCrash();
182 EXPECT_EQ(1, counter);
183 EXPECT_FALSE(IsChannelEstablished());
185 EXPECT_TRUE(IsChannelEstablished());
188 } // namespace content