Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: content/browser/compositor/gpu_process_transport_factory.cc

Issue 648413004: Make browser GPU channel creation async. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/compositor/gpu_process_transport_factory.h" 5 #include "content/browser/compositor/gpu_process_transport_factory.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 90
91 GpuProcessTransportFactory::~GpuProcessTransportFactory() { 91 GpuProcessTransportFactory::~GpuProcessTransportFactory() {
92 DCHECK(per_compositor_data_.empty()); 92 DCHECK(per_compositor_data_.empty());
93 93
94 // Make sure the lost context callback doesn't try to run during destruction. 94 // Make sure the lost context callback doesn't try to run during destruction.
95 callback_factory_.InvalidateWeakPtrs(); 95 callback_factory_.InvalidateWeakPtrs();
96 } 96 }
97 97
98 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> 98 scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
99 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext() { 99 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext() {
100 return CreateContextCommon(0); 100 CauseForGpuLaunch cause =
101 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
102 scoped_refptr<GpuChannelHost> gpu_channel_host(
103 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannelSync(cause));
104 return CreateContextCommon(gpu_channel_host, 0);
101 } 105 }
102 106
103 scoped_ptr<cc::SoftwareOutputDevice> CreateSoftwareOutputDevice( 107 scoped_ptr<cc::SoftwareOutputDevice> CreateSoftwareOutputDevice(
104 ui::Compositor* compositor) { 108 ui::Compositor* compositor) {
105 #if defined(OS_WIN) 109 #if defined(OS_WIN)
106 return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceWin( 110 return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceWin(
107 compositor)); 111 compositor));
108 #elif defined(USE_OZONE) 112 #elif defined(USE_OZONE)
109 return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceOzone( 113 return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceOzone(
110 compositor)); 114 compositor));
(...skipping 17 matching lines...) Expand all
128 if (overlay_candidates && 132 if (overlay_candidates &&
129 base::CommandLine::ForCurrentProcess()->HasSwitch( 133 base::CommandLine::ForCurrentProcess()->HasSwitch(
130 switches::kEnableHardwareOverlays)) { 134 switches::kEnableHardwareOverlays)) {
131 return scoped_ptr<cc::OverlayCandidateValidator>( 135 return scoped_ptr<cc::OverlayCandidateValidator>(
132 new OverlayCandidateValidatorOzone(widget, overlay_candidates)); 136 new OverlayCandidateValidatorOzone(widget, overlay_candidates));
133 } 137 }
134 #endif 138 #endif
135 return scoped_ptr<cc::OverlayCandidateValidator>(); 139 return scoped_ptr<cc::OverlayCandidateValidator>();
136 } 140 }
137 141
138 scoped_ptr<cc::OutputSurface> GpuProcessTransportFactory::CreateOutputSurface( 142 void GpuProcessTransportFactory::CreateOutputSurface(
139 ui::Compositor* compositor, bool software_fallback) { 143 base::WeakPtr<ui::Compositor> compositor,
140 PerCompositorData* data = per_compositor_data_[compositor]; 144 bool software_fallback) {
145 DCHECK(!!compositor);
146 PerCompositorData* data = per_compositor_data_[compositor.get()];
141 if (!data) 147 if (!data)
142 data = CreatePerCompositorData(compositor); 148 data = CreatePerCompositorData(compositor.get());
143 149
144 bool create_software_renderer = software_fallback; 150 bool create_software_renderer = software_fallback;
145 #if defined(OS_CHROMEOS) 151 #if defined(OS_CHROMEOS)
146 // Software fallback does not happen on Chrome OS. 152 // Software fallback does not happen on Chrome OS.
147 create_software_renderer = false; 153 create_software_renderer = false;
148 #elif defined(OS_WIN) 154 #elif defined(OS_WIN)
149 if (::GetProp(compositor->widget(), kForceSoftwareCompositor)) { 155 if (::GetProp(compositor->widget(), kForceSoftwareCompositor)) {
150 if (::RemoveProp(compositor->widget(), kForceSoftwareCompositor)) 156 if (::RemoveProp(compositor->widget(), kForceSoftwareCompositor))
151 create_software_renderer = true; 157 create_software_renderer = true;
152 } 158 }
153 #endif 159 #endif
154 160 if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor())
155 scoped_refptr<ContextProviderCommandBuffer> context_provider; 161 create_software_renderer = true;
156 162
157 if (!create_software_renderer) { 163 if (!create_software_renderer) {
164 CauseForGpuLaunch cause =
165 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
166 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel(
167 cause,
168 base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel,
169 callback_factory_.GetWeakPtr(),
170 compositor,
171 create_software_renderer));
172 } else {
173 EstablishedGpuChannel(compositor, create_software_renderer);
174 }
175 }
176
177 void GpuProcessTransportFactory::EstablishedGpuChannel(
178 base::WeakPtr<ui::Compositor> compositor,
179 bool create_software_renderer) {
180 if (!compositor)
181 return;
182 PerCompositorData* data = per_compositor_data_[compositor.get()];
183 DCHECK(data);
184 scoped_refptr<GpuChannelHost> gpu_channel_host =
185 BrowserGpuChannelHostFactory::instance()->GetGpuChannel();
186 scoped_refptr<ContextProviderCommandBuffer> context_provider;
187 if (gpu_channel_host.get() && !create_software_renderer) {
158 context_provider = ContextProviderCommandBuffer::Create( 188 context_provider = ContextProviderCommandBuffer::Create(
159 GpuProcessTransportFactory::CreateContextCommon(data->surface_id), 189 GpuProcessTransportFactory::CreateContextCommon(gpu_channel_host,
190 data->surface_id),
160 "Compositor"); 191 "Compositor");
161 } 192 }
162 193
163 UMA_HISTOGRAM_BOOLEAN("Aura.CreatedGpuBrowserCompositor", 194 UMA_HISTOGRAM_BOOLEAN("Aura.CreatedGpuBrowserCompositor",
164 !!context_provider.get()); 195 !!context_provider.get());
165 196
166 if (context_provider.get()) { 197 if (context_provider.get()) {
167 scoped_refptr<base::SingleThreadTaskRunner> compositor_thread_task_runner = 198 scoped_refptr<base::SingleThreadTaskRunner> compositor_thread_task_runner =
168 GetCompositorMessageLoop(); 199 GetCompositorMessageLoop();
169 if (!compositor_thread_task_runner.get()) 200 if (!compositor_thread_task_runner.get())
170 compositor_thread_task_runner = base::MessageLoopProxy::current(); 201 compositor_thread_task_runner = base::MessageLoopProxy::current();
171 202
172 // Here we know the GpuProcessHost has been set up, because we created a 203 // Here we know the GpuProcessHost has been set up, because we created a
173 // context. 204 // context.
174 output_surface_proxy_->ConnectToGpuProcessHost( 205 output_surface_proxy_->ConnectToGpuProcessHost(
175 compositor_thread_task_runner.get()); 206 compositor_thread_task_runner.get());
176 } 207 }
177 208
178 if (UseSurfacesEnabled()) { 209 if (UseSurfacesEnabled()) {
179 // This gets a bit confusing. Here we have a ContextProvider configured to 210 // This gets a bit confusing. Here we have a ContextProvider configured to
180 // render directly to this widget. We need to make an OnscreenDisplayClient 211 // render directly to this widget. We need to make an OnscreenDisplayClient
181 // associated with this context, then return a SurfaceDisplayOutputSurface 212 // associated with this context, then return a SurfaceDisplayOutputSurface
182 // set up to draw to the display's surface. 213 // set up to draw to the display's surface.
183 cc::SurfaceManager* manager = surface_manager_.get(); 214 cc::SurfaceManager* manager = surface_manager_.get();
184 scoped_ptr<cc::OutputSurface> display_surface; 215 scoped_ptr<cc::OutputSurface> display_surface;
185 if (!context_provider.get()) { 216 if (!context_provider.get()) {
186 display_surface = 217 display_surface =
187 make_scoped_ptr(new SoftwareBrowserCompositorOutputSurface( 218 make_scoped_ptr(new SoftwareBrowserCompositorOutputSurface(
188 output_surface_proxy_, 219 output_surface_proxy_,
189 CreateSoftwareOutputDevice(compositor), 220 CreateSoftwareOutputDevice(compositor.get()),
190 per_compositor_data_[compositor]->surface_id, 221 data->surface_id,
191 &output_surface_map_, 222 &output_surface_map_,
192 compositor->vsync_manager())); 223 compositor->vsync_manager()));
193 } else { 224 } else {
194 display_surface = make_scoped_ptr(new GpuBrowserCompositorOutputSurface( 225 display_surface = make_scoped_ptr(new GpuBrowserCompositorOutputSurface(
195 context_provider, 226 context_provider,
196 per_compositor_data_[compositor]->surface_id, 227 data->surface_id,
197 &output_surface_map_, 228 &output_surface_map_,
198 compositor->vsync_manager(), 229 compositor->vsync_manager(),
199 CreateOverlayCandidateValidator(compositor->widget()))); 230 CreateOverlayCandidateValidator(compositor->widget())));
200 } 231 }
201 scoped_ptr<OnscreenDisplayClient> display_client(new OnscreenDisplayClient( 232 scoped_ptr<OnscreenDisplayClient> display_client(new OnscreenDisplayClient(
202 display_surface.Pass(), manager, compositor->task_runner())); 233 display_surface.Pass(), manager, compositor->task_runner()));
203 234
204 scoped_ptr<SurfaceDisplayOutputSurface> output_surface( 235 scoped_ptr<SurfaceDisplayOutputSurface> output_surface(
205 new SurfaceDisplayOutputSurface( 236 new SurfaceDisplayOutputSurface(
206 manager, compositor->surface_id_allocator(), context_provider)); 237 manager, compositor->surface_id_allocator(), context_provider));
207 display_client->set_surface_output_surface(output_surface.get()); 238 display_client->set_surface_output_surface(output_surface.get());
208 output_surface->set_display_client(display_client.get()); 239 output_surface->set_display_client(display_client.get());
209 data->display_client = display_client.Pass(); 240 data->display_client = display_client.Pass();
210 return output_surface.Pass(); 241 compositor->SetOutputSurface(output_surface.Pass());
242 return;
211 } 243 }
212 244
213 if (!context_provider.get()) { 245 if (!context_provider.get()) {
214 if (compositor_thread_.get()) { 246 if (compositor_thread_.get()) {
215 LOG(FATAL) << "Failed to create UI context, but can't use software" 247 LOG(FATAL) << "Failed to create UI context, but can't use software"
216 " compositing with browser threaded compositing. Aborting."; 248 " compositing with browser threaded compositing. Aborting.";
217 } 249 }
218 250
219 return make_scoped_ptr(new SoftwareBrowserCompositorOutputSurface( 251 scoped_ptr<SoftwareBrowserCompositorOutputSurface> surface(
220 output_surface_proxy_, 252 new SoftwareBrowserCompositorOutputSurface(
221 CreateSoftwareOutputDevice(compositor), 253 output_surface_proxy_,
222 per_compositor_data_[compositor]->surface_id, 254 CreateSoftwareOutputDevice(compositor.get()),
223 &output_surface_map_, 255 data->surface_id,
224 compositor->vsync_manager())); 256 &output_surface_map_,
257 compositor->vsync_manager()));
258 compositor->SetOutputSurface(surface.Pass());
259 return;
225 } 260 }
226 261
227 scoped_ptr<BrowserCompositorOutputSurface> surface; 262 scoped_ptr<BrowserCompositorOutputSurface> surface;
228 #if defined(USE_OZONE) 263 #if defined(USE_OZONE)
229 if (ui::SurfaceFactoryOzone::GetInstance()->CanShowPrimaryPlaneAsOverlay()) { 264 if (ui::SurfaceFactoryOzone::GetInstance()->CanShowPrimaryPlaneAsOverlay()) {
230 surface.reset(new GpuSurfacelessBrowserCompositorOutputSurface( 265 surface.reset(new GpuSurfacelessBrowserCompositorOutputSurface(
231 context_provider, 266 context_provider,
232 per_compositor_data_[compositor]->surface_id, 267 data->surface_id,
233 &output_surface_map_, 268 &output_surface_map_,
234 compositor->vsync_manager(), 269 compositor->vsync_manager(),
235 CreateOverlayCandidateValidator(compositor->widget()), 270 CreateOverlayCandidateValidator(compositor->widget()),
236 GL_RGB, 271 GL_RGB,
237 compositor_thread_ != nullptr)); 272 compositor_thread_ != nullptr));
238 } 273 }
239 #endif 274 #endif
240 if (!surface) 275 if (!surface)
241 surface.reset(new GpuBrowserCompositorOutputSurface( 276 surface.reset(new GpuBrowserCompositorOutputSurface(
242 context_provider, 277 context_provider,
243 per_compositor_data_[compositor]->surface_id, 278 data->surface_id,
244 &output_surface_map_, 279 &output_surface_map_,
245 compositor->vsync_manager(), 280 compositor->vsync_manager(),
246 CreateOverlayCandidateValidator(compositor->widget()))); 281 CreateOverlayCandidateValidator(compositor->widget())));
247 282
248 if (data->reflector.get()) 283 if (data->reflector.get())
249 data->reflector->ReattachToOutputSurfaceFromMainThread(surface.get()); 284 data->reflector->ReattachToOutputSurfaceFromMainThread(surface.get());
250 285
251 return surface.Pass(); 286 compositor->SetOutputSurface(surface.Pass());
252 } 287 }
253 288
254 scoped_refptr<ui::Reflector> GpuProcessTransportFactory::CreateReflector( 289 scoped_refptr<ui::Reflector> GpuProcessTransportFactory::CreateReflector(
255 ui::Compositor* source, 290 ui::Compositor* source,
256 ui::Layer* target) { 291 ui::Layer* target) {
257 PerCompositorData* data = per_compositor_data_[source]; 292 PerCompositorData* data = per_compositor_data_[source];
258 DCHECK(data); 293 DCHECK(data);
259 294
260 data->reflector = new ReflectorImpl(source, 295 data->reflector = new ReflectorImpl(source,
261 target, 296 target,
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 tracker->SetSurfaceHandle( 445 tracker->SetSurfaceHandle(
411 data->surface_id, 446 data->surface_id,
412 gfx::GLSurfaceHandle(widget, gfx::NATIVE_DIRECT)); 447 gfx::GLSurfaceHandle(widget, gfx::NATIVE_DIRECT));
413 448
414 per_compositor_data_[compositor] = data; 449 per_compositor_data_[compositor] = data;
415 450
416 return data; 451 return data;
417 } 452 }
418 453
419 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> 454 scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
420 GpuProcessTransportFactory::CreateContextCommon(int surface_id) { 455 GpuProcessTransportFactory::CreateContextCommon(
456 scoped_refptr<GpuChannelHost> gpu_channel_host,
457 int surface_id) {
421 if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()) 458 if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor())
422 return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>(); 459 return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
423 blink::WebGraphicsContext3D::Attributes attrs; 460 blink::WebGraphicsContext3D::Attributes attrs;
424 attrs.shareResources = true; 461 attrs.shareResources = true;
425 attrs.depth = false; 462 attrs.depth = false;
426 attrs.stencil = false; 463 attrs.stencil = false;
427 attrs.antialias = false; 464 attrs.antialias = false;
428 attrs.noAutomaticFlushes = true; 465 attrs.noAutomaticFlushes = true;
429 bool lose_context_when_out_of_memory = true; 466 bool lose_context_when_out_of_memory = true;
430 CauseForGpuLaunch cause =
431 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
432 scoped_refptr<GpuChannelHost> gpu_channel_host(
433 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannelSync(cause));
434 if (!gpu_channel_host.get()) { 467 if (!gpu_channel_host.get()) {
435 LOG(ERROR) << "Failed to establish GPU channel."; 468 LOG(ERROR) << "Failed to establish GPU channel.";
436 return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>(); 469 return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
437 } 470 }
438 GURL url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon"); 471 GURL url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon");
439 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context( 472 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
440 new WebGraphicsContext3DCommandBufferImpl( 473 new WebGraphicsContext3DCommandBufferImpl(
441 surface_id, 474 surface_id,
442 url, 475 url,
443 gpu_channel_host.get(), 476 gpu_channel_host.get(),
(...skipping 27 matching lines...) Expand all
471 FOR_EACH_OBSERVER(ImageTransportFactoryObserver, 504 FOR_EACH_OBSERVER(ImageTransportFactoryObserver,
472 observer_list_, 505 observer_list_,
473 OnLostResources()); 506 OnLostResources());
474 507
475 // Kill things that use the shared context before killing the shared context. 508 // Kill things that use the shared context before killing the shared context.
476 lost_gl_helper.reset(); 509 lost_gl_helper.reset();
477 lost_shared_main_thread_contexts = NULL; 510 lost_shared_main_thread_contexts = NULL;
478 } 511 }
479 512
480 } // namespace content 513 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/compositor/gpu_process_transport_factory.h ('k') | mojo/aura/surface_context_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698