| 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 |