b343f1a10106b3c67a1ac2890e4330ccfa45463a
[platform/framework/web/crosswalk.git] / src / content / browser / gpu / gpu_ipc_browsertests.cc
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     scoped_refptr<content::GpuChannelHost> gpu_channel_host(
39         factory->EstablishGpuChannelSync(kInitCause));
40     context_.reset(
41         WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
42             gpu_channel_host.get(),
43             blink::WebGraphicsContext3D::Attributes(),
44             GURL(),
45             WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
46             NULL));
47     CHECK(context_.get());
48     context_->makeContextCurrent();
49     context_support_ = context_->GetContextSupport();
50     ContentBrowserTest::SetUpOnMainThread();
51   }
52
53   virtual void TearDownOnMainThread() OVERRIDE {
54     // Must delete the context first.
55     context_.reset(NULL);
56     ContentBrowserTest::TearDownOnMainThread();
57   }
58
59  protected:
60   scoped_ptr<content::WebGraphicsContext3DCommandBufferImpl> context_;
61   gpu::ContextSupport* context_support_;
62 };
63
64 }  // namespace
65
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"
69
70 namespace content {
71
72 class BrowserGpuChannelHostFactoryTest : public ContextTestBase {
73  public:
74   virtual void SetUpOnMainThread() OVERRIDE {
75     if (!BrowserGpuChannelHostFactory::CanUseForTesting())
76       return;
77
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);
82
83     CHECK(GetFactory());
84
85     ContentBrowserTest::SetUpOnMainThread();
86   }
87
88   virtual void TearDownOnMainThread() OVERRIDE {
89     ContextTestBase::TearDownOnMainThread();
90   }
91
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);
96   }
97
98   void OnContextLost(const base::Closure callback, int* counter) {
99     (*counter)++;
100     callback.Run();
101   }
102
103  protected:
104   BrowserGpuChannelHostFactory* GetFactory() {
105     return BrowserGpuChannelHostFactory::instance();
106   }
107
108   bool IsChannelEstablished() {
109     return GetFactory()->GetGpuChannel() != NULL;
110   }
111
112   void EstablishAndWait() {
113     base::RunLoop run_loop;
114     GetFactory()->EstablishGpuChannel(kInitCause, run_loop.QuitClosure());
115     run_loop.Run();
116   }
117
118   GpuChannelHost* GetGpuChannel() {
119     return GetFactory()->GetGpuChannel();
120   }
121
122   static void Signal(bool *event) {
123     CHECK_EQ(*event, false);
124     *event = true;
125   }
126
127   scoped_ptr<WebGraphicsContext3DCommandBufferImpl> CreateContext() {
128     return make_scoped_ptr(
129         WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
130             GetGpuChannel(),
131             blink::WebGraphicsContext3D::Attributes(),
132             GURL(),
133             WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
134             NULL));
135   }
136 };
137
138 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, Basic) {
139   if (!context_)
140     return;
141
142   DCHECK(!IsChannelEstablished());
143   EstablishAndWait();
144   EXPECT_TRUE(GetGpuChannel() != NULL);
145 }
146
147 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest,
148                        EstablishAndTerminate) {
149   if (!context_)
150     return;
151
152   DCHECK(!IsChannelEstablished());
153   base::RunLoop run_loop;
154   GetFactory()->EstablishGpuChannel(kInitCause, run_loop.QuitClosure());
155   GetFactory()->Terminate();
156
157   // The callback should still trigger.
158   run_loop.Run();
159 }
160
161 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, AlreadyEstablished) {
162   if (!context_)
163     return;
164
165   DCHECK(!IsChannelEstablished());
166   scoped_refptr<GpuChannelHost> gpu_channel =
167       GetFactory()->EstablishGpuChannelSync(kInitCause);
168
169   // Expect established callback immediately.
170   bool event = false;
171   GetFactory()->EstablishGpuChannel(
172       kInitCause,
173       base::Bind(&BrowserGpuChannelHostFactoryTest::Signal, &event));
174   EXPECT_TRUE(event);
175   EXPECT_EQ(gpu_channel, GetGpuChannel());
176 }
177
178 IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, CrashAndRecover) {
179   if (!context_)
180     return;
181
182   DCHECK(!IsChannelEstablished());
183   EstablishAndWait();
184   scoped_refptr<GpuChannelHost> host = GetGpuChannel();
185
186   scoped_refptr<ContextProviderCommandBuffer> provider =
187       ContextProviderCommandBuffer::Create(CreateContext(),
188                                            "BrowserGpuChannelHostFactoryTest");
189   base::RunLoop run_loop;
190   int counter = 0;
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();
199   run_loop.Run();
200
201   EXPECT_EQ(1, counter);
202   EXPECT_FALSE(IsChannelEstablished());
203   EstablishAndWait();
204   EXPECT_TRUE(IsChannelEstablished());
205 }
206
207 }  // namespace content