OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |