| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/android/blimp/chrome_compositor_dependencies.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/command_line.h" | |
| 9 #include "cc/output/context_provider.h" | |
| 10 #include "content/public/common/content_switches.h" | |
| 11 #include "gpu/command_buffer/client/gles2_interface.h" | |
| 12 #include "gpu/command_buffer/client/shared_memory_limits.h" | |
| 13 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | |
| 14 #include "gpu/ipc/client/gpu_channel_host.h" | |
| 15 | |
| 16 namespace { | |
| 17 | |
| 18 bool IsValidWorkerContext(cc::ContextProvider* context_provider) { | |
| 19 cc::ContextProvider::ScopedContextLock lock(context_provider); | |
| 20 return context_provider->ContextGL()->GetGraphicsResetStatusKHR() == | |
| 21 GL_NO_ERROR; | |
| 22 } | |
| 23 | |
| 24 gpu::gles2::ContextCreationAttribHelper | |
| 25 GetOffscreenContextCreationAttributes() { | |
| 26 gpu::gles2::ContextCreationAttribHelper attributes; | |
| 27 attributes.alpha_size = -1; | |
| 28 attributes.depth_size = 0; | |
| 29 attributes.stencil_size = 0; | |
| 30 attributes.samples = 0; | |
| 31 attributes.sample_buffers = 0; | |
| 32 attributes.bind_generates_resource = false; | |
| 33 attributes.lose_context_when_out_of_memory = true; | |
| 34 return attributes; | |
| 35 } | |
| 36 | |
| 37 bool IsAsyncWorkerContextEnabled() { | |
| 38 const base::CommandLine& command_line = | |
| 39 *base::CommandLine::ForCurrentProcess(); | |
| 40 | |
| 41 if (command_line.HasSwitch(switches::kDisableGpuAsyncWorkerContext)) | |
| 42 return false; | |
| 43 else if (command_line.HasSwitch(switches::kEnableGpuAsyncWorkerContext)) | |
| 44 return true; | |
| 45 | |
| 46 return false; | |
| 47 } | |
| 48 | |
| 49 } // namespace | |
| 50 | |
| 51 ChromeCompositorDependencies::ChromeCompositorDependencies( | |
| 52 ui::ContextProviderFactory* context_provider_factory) | |
| 53 : context_provider_factory_(context_provider_factory), weak_factory_(this) { | |
| 54 DCHECK(context_provider_factory_); | |
| 55 } | |
| 56 | |
| 57 ChromeCompositorDependencies::~ChromeCompositorDependencies() = default; | |
| 58 | |
| 59 gpu::GpuMemoryBufferManager* | |
| 60 ChromeCompositorDependencies::GetGpuMemoryBufferManager() { | |
| 61 return context_provider_factory_->GetGpuMemoryBufferManager(); | |
| 62 } | |
| 63 | |
| 64 cc::SurfaceManager* ChromeCompositorDependencies::GetSurfaceManager() { | |
| 65 return context_provider_factory_->GetSurfaceManager(); | |
| 66 } | |
| 67 | |
| 68 cc::FrameSinkId ChromeCompositorDependencies::AllocateFrameSinkId() { | |
| 69 return context_provider_factory_->AllocateFrameSinkId(); | |
| 70 } | |
| 71 | |
| 72 void ChromeCompositorDependencies::GetContextProviders( | |
| 73 const ContextProviderCallback& callback) { | |
| 74 context_provider_factory_->RequestGpuChannelHost( | |
| 75 base::Bind(&ChromeCompositorDependencies::OnGpuChannelEstablished, | |
| 76 weak_factory_.GetWeakPtr(), callback)); | |
| 77 } | |
| 78 | |
| 79 void ChromeCompositorDependencies::OnGpuChannelEstablished( | |
| 80 const ContextProviderCallback& callback, | |
| 81 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, | |
| 82 ui::ContextProviderFactory::GpuChannelHostResult result) { | |
| 83 using GpuRequestResult = ui::ContextProviderFactory::GpuChannelHostResult; | |
| 84 | |
| 85 switch (result) { | |
| 86 case GpuRequestResult::FAILURE_GPU_PROCESS_INITIALIZATION_FAILED: | |
| 87 // Pass the null result to the caller and let them try again. | |
| 88 break; | |
| 89 case GpuRequestResult::FAILURE_FACTORY_SHUTDOWN: | |
| 90 // If the factory is shutting down, early out and drop the requests. | |
| 91 return; | |
| 92 case GpuRequestResult::SUCCESS: | |
| 93 // Create the worker context first if necessary. | |
| 94 if (!shared_main_thread_worker_context_ || | |
| 95 !IsValidWorkerContext(shared_main_thread_worker_context_.get())) { | |
| 96 shared_main_thread_worker_context_ = | |
| 97 context_provider_factory_->CreateOffscreenContextProvider( | |
| 98 ui::ContextProviderFactory::ContextType:: | |
| 99 BLIMP_RENDER_WORKER_CONTEXT, | |
| 100 gpu::SharedMemoryLimits(), | |
| 101 GetOffscreenContextCreationAttributes(), | |
| 102 true /* support_locking */, false /* automatic_flushes */, | |
| 103 nullptr, gpu_channel_host); | |
| 104 if (!shared_main_thread_worker_context_->BindToCurrentThread()) { | |
| 105 shared_main_thread_worker_context_ = nullptr; | |
| 106 } | |
| 107 } | |
| 108 break; | |
| 109 } | |
| 110 | |
| 111 scoped_refptr<cc::ContextProvider> compositor_context_provider; | |
| 112 if (gpu_channel_host && shared_main_thread_worker_context_) { | |
| 113 // The compositor context shares resources with the worker context unless | |
| 114 // the worker is async. | |
| 115 cc::ContextProvider* shared_context = | |
| 116 IsAsyncWorkerContextEnabled() | |
| 117 ? nullptr | |
| 118 : shared_main_thread_worker_context_.get(); | |
| 119 | |
| 120 compositor_context_provider = | |
| 121 context_provider_factory_->CreateOffscreenContextProvider( | |
| 122 ui::ContextProviderFactory::ContextType:: | |
| 123 BLIMP_RENDER_COMPOSITOR_CONTEXT, | |
| 124 gpu::SharedMemoryLimits::ForMailboxContext(), | |
| 125 GetOffscreenContextCreationAttributes(), | |
| 126 false /* support_locking */, false /* automatic_flushes */, | |
| 127 shared_context, std::move(gpu_channel_host)); | |
| 128 } | |
| 129 | |
| 130 callback.Run(compositor_context_provider, shared_main_thread_worker_context_); | |
| 131 } | |
| OLD | NEW |