Chromium Code Reviews| 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 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 100 using gpu::gles2::GLES2Interface; | 100 using gpu::gles2::GLES2Interface; |
| 101 | 101 |
| 102 namespace { | 102 namespace { |
| 103 | 103 |
| 104 const int kNumRetriesBeforeSoftwareFallback = 4; | 104 const int kNumRetriesBeforeSoftwareFallback = 4; |
| 105 | 105 |
| 106 bool IsUsingMus() { | 106 bool IsUsingMus() { |
| 107 return shell::ShellIsRemote(); | 107 return shell::ShellIsRemote(); |
| 108 } | 108 } |
| 109 | 109 |
| 110 static bool ShouldCreateGpuOutputSurface(ui::Compositor* compositor) { | |
| 111 #if defined(OS_CHROMEOS) | |
| 112 // Software fallback does not happen on Chrome OS. | |
| 113 return true; | |
| 114 #endif | |
| 115 | |
| 116 if (IsUsingMus()) { | |
| 117 // There will always be a GPU process. | |
| 118 return true; | |
| 119 } | |
| 120 | |
| 121 #if defined(OS_WIN) | |
| 122 if (compositor && ::GetProp(compositor->widget(), kForceSoftwareCompositor) && | |
| 123 ::RemoveProp(compositor->widget(), kForceSoftwareCompositor)) | |
| 124 return false; | |
| 125 #endif | |
| 126 | |
| 127 return content::GpuDataManagerImpl::GetInstance() | |
| 128 ->CanUseGpuBrowserCompositor(); | |
| 129 } | |
| 130 | |
| 110 scoped_refptr<content::ContextProviderCommandBuffer> CreateContextCommon( | 131 scoped_refptr<content::ContextProviderCommandBuffer> CreateContextCommon( |
| 111 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, | 132 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, |
| 112 gpu::SurfaceHandle surface_handle, | 133 gpu::SurfaceHandle surface_handle, |
| 113 bool need_alpha_channel, | 134 bool need_alpha_channel, |
| 114 bool support_locking, | 135 bool support_locking, |
| 115 content::ContextProviderCommandBuffer* shared_context_provider, | 136 content::ContextProviderCommandBuffer* shared_context_provider, |
| 116 content::command_buffer_metrics::ContextType type) { | 137 content::command_buffer_metrics::ContextType type) { |
| 117 DCHECK( | 138 DCHECK(ShouldCreateGpuOutputSurface(nullptr)); |
|
danakj
2016/08/12 17:48:29
This is tied to the change for shared main thread
| |
| 118 content::GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()); | |
| 119 DCHECK(gpu_channel_host); | 139 DCHECK(gpu_channel_host); |
| 120 | 140 |
| 121 // This is called from a few places to create different contexts: | 141 // This is called from a few places to create different contexts: |
| 122 // - The shared main thread context (offscreen). | 142 // - The shared main thread context (offscreen). |
| 123 // - The compositor context, which is used by the browser compositor | 143 // - The compositor context, which is used by the browser compositor |
| 124 // (offscreen) for synchronization mostly, and by the display compositor | 144 // (offscreen) for synchronization mostly, and by the display compositor |
| 125 // (onscreen, except for with mus) for actual GL drawing. | 145 // (onscreen, except for with mus) for actual GL drawing. |
| 126 // - The compositor worker context (offscreen) used for GPU raster. | 146 // - The compositor worker context (offscreen) used for GPU raster. |
| 127 // So ask for capabilities needed by any of these cases (we can optimize by | 147 // So ask for capabilities needed by any of these cases (we can optimize by |
| 128 // branching on |surface_handle| being null if these needs diverge). | 148 // branching on |surface_handle| being null if these needs diverge). |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 257 ca_layers_disabled)); | 277 ca_layers_disabled)); |
| 258 } | 278 } |
| 259 #elif defined(OS_ANDROID) | 279 #elif defined(OS_ANDROID) |
| 260 validator.reset( | 280 validator.reset( |
| 261 new display_compositor::CompositorOverlayCandidateValidatorAndroid()); | 281 new display_compositor::CompositorOverlayCandidateValidatorAndroid()); |
| 262 #endif | 282 #endif |
| 263 | 283 |
| 264 return validator; | 284 return validator; |
| 265 } | 285 } |
| 266 | 286 |
| 267 static bool ShouldCreateGpuOutputSurface(ui::Compositor* compositor) { | |
| 268 #if defined(OS_CHROMEOS) | |
| 269 // Software fallback does not happen on Chrome OS. | |
| 270 return true; | |
| 271 #endif | |
| 272 | |
| 273 #if defined(OS_WIN) | |
| 274 if (::GetProp(compositor->widget(), kForceSoftwareCompositor) && | |
| 275 ::RemoveProp(compositor->widget(), kForceSoftwareCompositor)) | |
| 276 return false; | |
| 277 #endif | |
| 278 | |
| 279 return GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor(); | |
| 280 } | |
| 281 | |
| 282 void GpuProcessTransportFactory::CreateOutputSurface( | 287 void GpuProcessTransportFactory::CreateOutputSurface( |
| 283 base::WeakPtr<ui::Compositor> compositor) { | 288 base::WeakPtr<ui::Compositor> compositor) { |
| 284 DCHECK(!!compositor); | 289 DCHECK(!!compositor); |
| 285 PerCompositorData* data = per_compositor_data_[compositor.get()]; | 290 PerCompositorData* data = per_compositor_data_[compositor.get()]; |
| 286 if (!data) { | 291 if (!data) { |
| 287 data = CreatePerCompositorData(compositor.get()); | 292 data = CreatePerCompositorData(compositor.get()); |
| 288 } else { | 293 } else { |
| 289 // TODO(danakj): We can destroy the |data->display| here when the compositor | 294 // TODO(danakj): We can destroy the |data->display| here when the compositor |
| 290 // destroys its OutputSurface before calling back here. | 295 // destroys its OutputSurface before calling back here. |
| 291 data->display_output_surface = nullptr; | 296 data->display_output_surface = nullptr; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 327 return; | 332 return; |
| 328 | 333 |
| 329 PerCompositorData* data = it->second; | 334 PerCompositorData* data = it->second; |
| 330 DCHECK(data); | 335 DCHECK(data); |
| 331 | 336 |
| 332 if (num_attempts > kNumRetriesBeforeSoftwareFallback) { | 337 if (num_attempts > kNumRetriesBeforeSoftwareFallback) { |
| 333 #if defined(OS_CHROMEOS) | 338 #if defined(OS_CHROMEOS) |
| 334 LOG(FATAL) << "Unable to create a UI graphics context, and cannot use " | 339 LOG(FATAL) << "Unable to create a UI graphics context, and cannot use " |
| 335 << "software compositing on ChromeOS."; | 340 << "software compositing on ChromeOS."; |
| 336 #endif | 341 #endif |
| 337 create_gpu_output_surface = false; | 342 create_gpu_output_surface = false; |
|
danakj
2016/08/12 17:48:29
You probably want to not do this on mus too no?
| |
| 338 } | 343 } |
| 339 | 344 |
| 340 #if defined(OS_WIN) | 345 #if defined(OS_WIN) |
| 341 gfx::RenderingWindowManager::GetInstance()->RegisterParent( | 346 gfx::RenderingWindowManager::GetInstance()->RegisterParent( |
| 342 compositor->widget()); | 347 compositor->widget()); |
| 343 #endif | 348 #endif |
| 344 | 349 |
| 345 scoped_refptr<cc::VulkanInProcessContextProvider> vulkan_context_provider = | 350 scoped_refptr<cc::VulkanInProcessContextProvider> vulkan_context_provider = |
| 346 SharedVulkanContextProvider(); | 351 SharedVulkanContextProvider(); |
| 347 scoped_refptr<ContextProviderCommandBuffer> context_provider; | 352 scoped_refptr<ContextProviderCommandBuffer> context_provider; |
| 348 if (create_gpu_output_surface && !vulkan_context_provider) { | 353 if (create_gpu_output_surface && !vulkan_context_provider) { |
| 349 // Try to reuse existing worker context provider. | 354 // Try to reuse existing worker context provider. |
| 350 if (shared_worker_context_provider_) { | 355 if (shared_worker_context_provider_) { |
| 351 bool lost; | 356 bool lost; |
| 352 { | 357 { |
| 353 // Note: If context is lost, we delete reference after releasing the | 358 // Note: If context is lost, we delete reference after releasing the |
| 354 // lock. | 359 // lock. |
| 355 base::AutoLock lock(*shared_worker_context_provider_->GetLock()); | 360 base::AutoLock lock(*shared_worker_context_provider_->GetLock()); |
| 356 lost = shared_worker_context_provider_->ContextGL() | 361 lost = shared_worker_context_provider_->ContextGL() |
| 357 ->GetGraphicsResetStatusKHR() != GL_NO_ERROR; | 362 ->GetGraphicsResetStatusKHR() != GL_NO_ERROR; |
| 358 } | 363 } |
| 359 if (lost) | 364 if (lost) |
| 360 shared_worker_context_provider_ = nullptr; | 365 shared_worker_context_provider_ = nullptr; |
| 361 } | 366 } |
| 362 | 367 |
| 363 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host; | 368 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host; |
| 364 if (GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()) | 369 if (ShouldCreateGpuOutputSurface(nullptr)) |
|
danakj
2016/08/12 17:48:29
I don't think this should change. The fact that we
| |
| 365 gpu_channel_host = std::move(established_channel_host); | 370 gpu_channel_host = std::move(established_channel_host); |
| 366 | 371 |
| 367 if (!gpu_channel_host) { | 372 if (!gpu_channel_host) { |
| 368 shared_worker_context_provider_ = nullptr; | 373 shared_worker_context_provider_ = nullptr; |
| 369 } else { | 374 } else { |
| 370 if (!shared_worker_context_provider_) { | 375 if (!shared_worker_context_provider_) { |
| 371 bool need_alpha_channel = false; | 376 bool need_alpha_channel = false; |
| 372 const bool support_locking = true; | 377 const bool support_locking = true; |
| 373 shared_worker_context_provider_ = | 378 shared_worker_context_provider_ = |
| 374 CreateContextCommon(gpu_channel_host, gpu::kNullSurfaceHandle, | 379 CreateContextCommon(gpu_channel_host, gpu::kNullSurfaceHandle, |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 760 if (data->display_output_surface) | 765 if (data->display_output_surface) |
| 761 data->display_output_surface->SetSurfaceSuspendedForRecycle(suspended); | 766 data->display_output_surface->SetSurfaceSuspendedForRecycle(suspended); |
| 762 } | 767 } |
| 763 #endif | 768 #endif |
| 764 | 769 |
| 765 scoped_refptr<cc::ContextProvider> | 770 scoped_refptr<cc::ContextProvider> |
| 766 GpuProcessTransportFactory::SharedMainThreadContextProvider() { | 771 GpuProcessTransportFactory::SharedMainThreadContextProvider() { |
| 767 if (shared_main_thread_contexts_) | 772 if (shared_main_thread_contexts_) |
| 768 return shared_main_thread_contexts_; | 773 return shared_main_thread_contexts_; |
| 769 | 774 |
| 770 if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()) | 775 if (!ShouldCreateGpuOutputSurface(nullptr)) |
|
danakj
2016/08/12 17:48:29
This might be right but it has nothing to do with
| |
| 771 return nullptr; | 776 return nullptr; |
| 772 | 777 |
| 773 DCHECK(gpu_channel_factory_); | 778 DCHECK(gpu_channel_factory_); |
| 774 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host = | 779 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host = |
| 775 gpu_channel_factory_->EstablishGpuChannelSync(); | 780 gpu_channel_factory_->EstablishGpuChannelSync(); |
| 776 if (!gpu_channel_host) | 781 if (!gpu_channel_host) |
| 777 return nullptr; | 782 return nullptr; |
| 778 | 783 |
| 779 // We need a separate context from the compositor's so that skia and gl_helper | 784 // We need a separate context from the compositor's so that skia and gl_helper |
| 780 // don't step on each other. | 785 // don't step on each other. |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 859 shared_vulkan_context_provider_ = | 864 shared_vulkan_context_provider_ = |
| 860 cc::VulkanInProcessContextProvider::Create(); | 865 cc::VulkanInProcessContextProvider::Create(); |
| 861 } | 866 } |
| 862 | 867 |
| 863 shared_vulkan_context_provider_initialized_ = true; | 868 shared_vulkan_context_provider_initialized_ = true; |
| 864 } | 869 } |
| 865 return shared_vulkan_context_provider_; | 870 return shared_vulkan_context_provider_; |
| 866 } | 871 } |
| 867 | 872 |
| 868 } // namespace content | 873 } // namespace content |
| OLD | NEW |