| 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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 const int kNumRetriesBeforeSoftwareFallback = 4; | 104 const int kNumRetriesBeforeSoftwareFallback = 4; |
| 105 | 105 |
| 106 bool IsUsingMus() { | 106 bool IsUsingMus() { |
| 107 return service_manager::ServiceManagerIsRemote(); | 107 return service_manager::ServiceManagerIsRemote(); |
| 108 } | 108 } |
| 109 | 109 |
| 110 scoped_refptr<ui::ContextProviderCommandBuffer> CreateContextCommon( | 110 scoped_refptr<ui::ContextProviderCommandBuffer> CreateContextCommon( |
| 111 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, | 111 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, |
| 112 gpu::SurfaceHandle surface_handle, | 112 gpu::SurfaceHandle surface_handle, |
| 113 bool need_alpha_channel, | 113 bool need_alpha_channel, |
| 114 bool need_stencil_bits, |
| 114 bool support_locking, | 115 bool support_locking, |
| 115 ui::ContextProviderCommandBuffer* shared_context_provider, | 116 ui::ContextProviderCommandBuffer* shared_context_provider, |
| 116 ui::command_buffer_metrics::ContextType type) { | 117 ui::command_buffer_metrics::ContextType type) { |
| 117 DCHECK( | 118 DCHECK( |
| 118 content::GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()); | 119 content::GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()); |
| 119 DCHECK(gpu_channel_host); | 120 DCHECK(gpu_channel_host); |
| 120 | 121 |
| 121 // This is called from a few places to create different contexts: | 122 // This is called from a few places to create different contexts: |
| 122 // - The shared main thread context (offscreen). | 123 // - The shared main thread context (offscreen). |
| 123 // - The compositor context, which is used by the browser compositor | 124 // - The compositor context, which is used by the browser compositor |
| 124 // (offscreen) for synchronization mostly, and by the display compositor | 125 // (offscreen) for synchronization mostly, and by the display compositor |
| 125 // (onscreen, except for with mus) for actual GL drawing. | 126 // (onscreen, except for with mus) for actual GL drawing. |
| 126 // - The compositor worker context (offscreen) used for GPU raster. | 127 // - The compositor worker context (offscreen) used for GPU raster. |
| 127 // So ask for capabilities needed by any of these cases (we can optimize by | 128 // 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). | 129 // branching on |surface_handle| being null if these needs diverge). |
| 129 // | 130 // |
| 130 // The default framebuffer for an offscreen context is not used, so it does | 131 // The default framebuffer for an offscreen context is not used, so it does |
| 131 // not need alpha, stencil, depth, antialiasing. The display compositor does | 132 // not need alpha, stencil, depth, antialiasing. The display compositor does |
| 132 // not use these things either, so we can request nothing here. | 133 // not use these things either (except for alpha when using mus for |
| 133 // The display compositor does not use these things either (except for alpha | 134 // non-opaque ui that overlaps the system's window borders or stencil bits |
| 134 // when using mus for non-opaque ui that overlaps the system's window | 135 // for overdraw feedback), so we can request only that when needed. |
| 135 // borders), so we can request only that when needed. | |
| 136 gpu::gles2::ContextCreationAttribHelper attributes; | 136 gpu::gles2::ContextCreationAttribHelper attributes; |
| 137 attributes.alpha_size = need_alpha_channel ? 8 : -1; | 137 attributes.alpha_size = need_alpha_channel ? 8 : -1; |
| 138 attributes.depth_size = 0; | 138 attributes.depth_size = 0; |
| 139 attributes.stencil_size = 0; | 139 attributes.stencil_size = need_stencil_bits ? 8 : 0; |
| 140 attributes.samples = 0; | 140 attributes.samples = 0; |
| 141 attributes.sample_buffers = 0; | 141 attributes.sample_buffers = 0; |
| 142 attributes.bind_generates_resource = false; | 142 attributes.bind_generates_resource = false; |
| 143 attributes.lose_context_when_out_of_memory = true; | 143 attributes.lose_context_when_out_of_memory = true; |
| 144 attributes.buffer_preserved = false; | 144 attributes.buffer_preserved = false; |
| 145 | 145 |
| 146 constexpr bool automatic_flushes = false; | 146 constexpr bool automatic_flushes = false; |
| 147 | 147 |
| 148 GURL url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon"); | 148 GURL url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon"); |
| 149 return make_scoped_refptr(new ui::ContextProviderCommandBuffer( | 149 return make_scoped_refptr(new ui::ContextProviderCommandBuffer( |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 if (num_attempts > kNumRetriesBeforeSoftwareFallback) { | 340 if (num_attempts > kNumRetriesBeforeSoftwareFallback) { |
| 341 bool fatal = IsUsingMus(); | 341 bool fatal = IsUsingMus(); |
| 342 #if defined(OS_CHROMEOS) | 342 #if defined(OS_CHROMEOS) |
| 343 fatal = true; | 343 fatal = true; |
| 344 #endif | 344 #endif |
| 345 LOG_IF(FATAL, fatal) << "Unable to create a UI graphics context, and " | 345 LOG_IF(FATAL, fatal) << "Unable to create a UI graphics context, and " |
| 346 << "cannot use software compositing on ChromeOS."; | 346 << "cannot use software compositing on ChromeOS."; |
| 347 create_gpu_output_surface = false; | 347 create_gpu_output_surface = false; |
| 348 } | 348 } |
| 349 | 349 |
| 350 bool supports_stencil = false; |
| 351 #if defined(OS_CHROMEOS) |
| 352 // ChromeOS uses surfaceless when running on a real device and stencil |
| 353 // buffers can then be added dynamically so supporting them does not have an |
| 354 // impact on normal usage. If we are not running on a real ChromeOS device |
| 355 // but instead on a workstation for development, then stencil support is |
| 356 // useful as it allows the overdraw feedback debugging feature to be used. |
| 357 supports_stencil = true; |
| 358 #endif |
| 359 |
| 350 #if defined(OS_WIN) | 360 #if defined(OS_WIN) |
| 351 gfx::RenderingWindowManager::GetInstance()->RegisterParent( | 361 gfx::RenderingWindowManager::GetInstance()->RegisterParent( |
| 352 compositor->widget()); | 362 compositor->widget()); |
| 353 #endif | 363 #endif |
| 354 | 364 |
| 355 scoped_refptr<cc::VulkanInProcessContextProvider> vulkan_context_provider = | 365 scoped_refptr<cc::VulkanInProcessContextProvider> vulkan_context_provider = |
| 356 SharedVulkanContextProvider(); | 366 SharedVulkanContextProvider(); |
| 357 scoped_refptr<ui::ContextProviderCommandBuffer> context_provider; | 367 scoped_refptr<ui::ContextProviderCommandBuffer> context_provider; |
| 358 if (create_gpu_output_surface && !vulkan_context_provider) { | 368 if (create_gpu_output_surface && !vulkan_context_provider) { |
| 359 // Try to reuse existing worker context provider. | 369 // Try to reuse existing worker context provider. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 375 gpu_channel_host = std::move(established_channel_host); | 385 gpu_channel_host = std::move(established_channel_host); |
| 376 | 386 |
| 377 if (!gpu_channel_host) { | 387 if (!gpu_channel_host) { |
| 378 shared_worker_context_provider_ = nullptr; | 388 shared_worker_context_provider_ = nullptr; |
| 379 } else { | 389 } else { |
| 380 if (!shared_worker_context_provider_) { | 390 if (!shared_worker_context_provider_) { |
| 381 bool need_alpha_channel = false; | 391 bool need_alpha_channel = false; |
| 382 const bool support_locking = true; | 392 const bool support_locking = true; |
| 383 shared_worker_context_provider_ = CreateContextCommon( | 393 shared_worker_context_provider_ = CreateContextCommon( |
| 384 gpu_channel_host, gpu::kNullSurfaceHandle, need_alpha_channel, | 394 gpu_channel_host, gpu::kNullSurfaceHandle, need_alpha_channel, |
| 385 support_locking, nullptr, | 395 false, support_locking, nullptr, |
| 386 ui::command_buffer_metrics::BROWSER_WORKER_CONTEXT); | 396 ui::command_buffer_metrics::BROWSER_WORKER_CONTEXT); |
| 387 // TODO(vadimt): Remove ScopedTracker below once crbug.com/125248 is | 397 // TODO(vadimt): Remove ScopedTracker below once crbug.com/125248 is |
| 388 // fixed. Tracking time in BindToCurrentThread. | 398 // fixed. Tracking time in BindToCurrentThread. |
| 389 tracked_objects::ScopedTracker tracking_profile( | 399 tracked_objects::ScopedTracker tracking_profile( |
| 390 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 400 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 391 "125248" | 401 "125248" |
| 392 " GpuProcessTransportFactory::EstablishedGpuChannel" | 402 " GpuProcessTransportFactory::EstablishedGpuChannel" |
| 393 "::Worker")); | 403 "::Worker")); |
| 394 if (!shared_worker_context_provider_->BindToCurrentThread()) | 404 if (!shared_worker_context_provider_->BindToCurrentThread()) |
| 395 shared_worker_context_provider_ = nullptr; | 405 shared_worker_context_provider_ = nullptr; |
| 396 } | 406 } |
| 397 | 407 |
| 398 // The |context_provider| is used for both the browser compositor and the | 408 // The |context_provider| is used for both the browser compositor and the |
| 399 // display compositor. It shares resources with the worker context, so if | 409 // display compositor. It shares resources with the worker context, so if |
| 400 // we failed to make a worker context, just start over and try again. | 410 // we failed to make a worker context, just start over and try again. |
| 401 if (shared_worker_context_provider_) { | 411 if (shared_worker_context_provider_) { |
| 402 // For mus, we create an offscreen context for a mus window, and we will | 412 // For mus, we create an offscreen context for a mus window, and we will |
| 403 // use CommandBufferProxyImpl::TakeFrontBuffer() to take the context's | 413 // use CommandBufferProxyImpl::TakeFrontBuffer() to take the context's |
| 404 // front buffer into a mailbox, insert a sync token, and send the | 414 // front buffer into a mailbox, insert a sync token, and send the |
| 405 // mailbox+sync to the ui service process. | 415 // mailbox+sync to the ui service process. |
| 406 gpu::SurfaceHandle surface_handle = | 416 gpu::SurfaceHandle surface_handle = |
| 407 IsUsingMus() ? gpu::kNullSurfaceHandle : data->surface_handle; | 417 IsUsingMus() ? gpu::kNullSurfaceHandle : data->surface_handle; |
| 408 bool need_alpha_channel = IsUsingMus(); | 418 bool need_alpha_channel = IsUsingMus(); |
| 409 bool support_locking = false; | 419 bool support_locking = false; |
| 410 context_provider = CreateContextCommon( | 420 context_provider = CreateContextCommon( |
| 411 std::move(gpu_channel_host), surface_handle, need_alpha_channel, | 421 std::move(gpu_channel_host), surface_handle, need_alpha_channel, |
| 412 support_locking, shared_worker_context_provider_.get(), | 422 supports_stencil, support_locking, |
| 423 shared_worker_context_provider_.get(), |
| 413 ui::command_buffer_metrics::DISPLAY_COMPOSITOR_ONSCREEN_CONTEXT); | 424 ui::command_buffer_metrics::DISPLAY_COMPOSITOR_ONSCREEN_CONTEXT); |
| 414 // TODO(vadimt): Remove ScopedTracker below once crbug.com/125248 is | 425 // TODO(vadimt): Remove ScopedTracker below once crbug.com/125248 is |
| 415 // fixed. Tracking time in BindToCurrentThread. | 426 // fixed. Tracking time in BindToCurrentThread. |
| 416 tracked_objects::ScopedTracker tracking_profile( | 427 tracked_objects::ScopedTracker tracking_profile( |
| 417 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 428 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 418 "125248" | 429 "125248" |
| 419 " GpuProcessTransportFactory::EstablishedGpuChannel" | 430 " GpuProcessTransportFactory::EstablishedGpuChannel" |
| 420 "::Compositor")); | 431 "::Compositor")); |
| 421 #if defined(OS_MACOSX) | 432 #if defined(OS_MACOSX) |
| 422 // On Mac, GpuCommandBufferMsg_SwapBuffersCompleted must be handled in | 433 // On Mac, GpuCommandBufferMsg_SwapBuffersCompleted must be handled in |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 validator; | 524 validator; |
| 514 const bool use_mus = IsUsingMus(); | 525 const bool use_mus = IsUsingMus(); |
| 515 #if !defined(OS_MACOSX) | 526 #if !defined(OS_MACOSX) |
| 516 // Overlays are only supported on surfaceless output surfaces on Mac. | 527 // Overlays are only supported on surfaceless output surfaces on Mac. |
| 517 if (!use_mus) | 528 if (!use_mus) |
| 518 validator = CreateOverlayCandidateValidator(compositor->widget()); | 529 validator = CreateOverlayCandidateValidator(compositor->widget()); |
| 519 #endif | 530 #endif |
| 520 if (!use_mus) { | 531 if (!use_mus) { |
| 521 display_output_surface = | 532 display_output_surface = |
| 522 base::MakeUnique<GpuBrowserCompositorOutputSurface>( | 533 base::MakeUnique<GpuBrowserCompositorOutputSurface>( |
| 523 context_provider, vsync_callback, std::move(validator)); | 534 context_provider, vsync_callback, std::move(validator), |
| 535 supports_stencil); |
| 524 } else { | 536 } else { |
| 525 #if defined(USE_AURA) | 537 #if defined(USE_AURA) |
| 526 std::unique_ptr<MusBrowserCompositorOutputSurface> mus_output_surface; | 538 std::unique_ptr<MusBrowserCompositorOutputSurface> mus_output_surface; |
| 527 if (compositor->window()) { | 539 if (compositor->window()) { |
| 528 // TODO(mfomitchev): Remove this clause once we complete the switch | 540 // TODO(mfomitchev): Remove this clause once we complete the switch |
| 529 // to Aura-Mus. | 541 // to Aura-Mus. |
| 530 mus_output_surface = | 542 mus_output_surface = |
| 531 base::MakeUnique<MusBrowserCompositorOutputSurface>( | 543 base::MakeUnique<MusBrowserCompositorOutputSurface>( |
| 532 compositor->window(), context_provider, | 544 compositor->window(), context_provider, |
| 533 GetGpuMemoryBufferManager(), vsync_callback, | 545 GetGpuMemoryBufferManager(), vsync_callback, |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 823 gpu_channel_factory_->EstablishGpuChannelSync(); | 835 gpu_channel_factory_->EstablishGpuChannelSync(); |
| 824 if (!gpu_channel_host) | 836 if (!gpu_channel_host) |
| 825 return nullptr; | 837 return nullptr; |
| 826 | 838 |
| 827 // We need a separate context from the compositor's so that skia and gl_helper | 839 // We need a separate context from the compositor's so that skia and gl_helper |
| 828 // don't step on each other. | 840 // don't step on each other. |
| 829 bool need_alpha_channel = false; | 841 bool need_alpha_channel = false; |
| 830 bool support_locking = false; | 842 bool support_locking = false; |
| 831 shared_main_thread_contexts_ = CreateContextCommon( | 843 shared_main_thread_contexts_ = CreateContextCommon( |
| 832 std::move(gpu_channel_host), gpu::kNullSurfaceHandle, need_alpha_channel, | 844 std::move(gpu_channel_host), gpu::kNullSurfaceHandle, need_alpha_channel, |
| 833 support_locking, nullptr, | 845 false, support_locking, nullptr, |
| 834 ui::command_buffer_metrics::BROWSER_OFFSCREEN_MAINTHREAD_CONTEXT); | 846 ui::command_buffer_metrics::BROWSER_OFFSCREEN_MAINTHREAD_CONTEXT); |
| 835 shared_main_thread_contexts_->SetLostContextCallback(base::Bind( | 847 shared_main_thread_contexts_->SetLostContextCallback(base::Bind( |
| 836 &GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback, | 848 &GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback, |
| 837 callback_factory_.GetWeakPtr())); | 849 callback_factory_.GetWeakPtr())); |
| 838 // TODO(vadimt): Remove ScopedTracker below once crbug.com/125248 is | 850 // TODO(vadimt): Remove ScopedTracker below once crbug.com/125248 is |
| 839 // fixed. Tracking time in BindToCurrentThread. | 851 // fixed. Tracking time in BindToCurrentThread. |
| 840 tracked_objects::ScopedTracker tracking_profile( | 852 tracked_objects::ScopedTracker tracking_profile( |
| 841 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 853 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 842 "125248" | 854 "125248" |
| 843 " GpuProcessTransportFactory::SharedMainThreadContextProvider")); | 855 " GpuProcessTransportFactory::SharedMainThreadContextProvider")); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 907 shared_vulkan_context_provider_ = | 919 shared_vulkan_context_provider_ = |
| 908 cc::VulkanInProcessContextProvider::Create(); | 920 cc::VulkanInProcessContextProvider::Create(); |
| 909 } | 921 } |
| 910 | 922 |
| 911 shared_vulkan_context_provider_initialized_ = true; | 923 shared_vulkan_context_provider_initialized_ = true; |
| 912 } | 924 } |
| 913 return shared_vulkan_context_provider_; | 925 return shared_vulkan_context_provider_; |
| 914 } | 926 } |
| 915 | 927 |
| 916 } // namespace content | 928 } // namespace content |
| OLD | NEW |