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:
SetUpOnMainThread()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_->InitializeOnCurrentThread();
51 context_support_ = context_->GetContextSupport();
52 ContentBrowserTest::SetUpOnMainThread();
53 }
54
TearDownOnMainThread()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:
SetUpOnMainThread()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
OnContextLost(const base::Closure callback,int * counter)90 void OnContextLost(const base::Closure callback, int* counter) {
91 (*counter)++;
92 callback.Run();
93 }
94
95 protected:
GetFactory()96 BrowserGpuChannelHostFactory* GetFactory() {
97 return BrowserGpuChannelHostFactory::instance();
98 }
99
IsChannelEstablished()100 bool IsChannelEstablished() {
101 return GetFactory()->GetGpuChannel() != NULL;
102 }
103
EstablishAndWait()104 void EstablishAndWait() {
105 base::RunLoop run_loop;
106 GetFactory()->EstablishGpuChannel(kInitCause, run_loop.QuitClosure());
107 run_loop.Run();
108 }
109
GetGpuChannel()110 GpuChannelHost* GetGpuChannel() {
111 return GetFactory()->GetGpuChannel();
112 }
113
Signal(bool * event)114 static void Signal(bool *event) {
115 CHECK_EQ(*event, false);
116 *event = true;
117 }
118
CreateContext()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.
IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest,DISABLED_Basic)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.
IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest,DISABLED_EstablishAndTerminate)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.
IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest,DISABLED_AlreadyEstablished)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.get(), GetGpuChannel());
165 }
166
167 // Fails since UI Compositor establishes a GpuChannel.
IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest,DISABLED_CrashAndRecover)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