Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(254)

Side by Side Diff: content/browser/renderer_host/context_provider_factory_impl_android.cc

Issue 2190033002: content: Add ContextProviderFactory to create a render ContextProvider. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Move ContextProviderFactory to ui Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 "content/browser/renderer_host/context_provider_factory_impl_android.h"
6
7 #include "base/auto_reset.h"
8 #include "base/command_line.h"
9 #include "base/lazy_instance.h"
10 #include "base/memory/singleton.h"
11 #include "cc/output/context_provider.h"
12 #include "cc/output/vulkan_in_process_context_provider.h"
13 #include "content/browser/gpu/browser_gpu_channel_host_factory.h"
14 #include "content/browser/gpu/compositor_util.h"
15 #include "content/common/gpu/client/context_provider_command_buffer.h"
16 #include "content/public/common/content_switches.h"
17 #include "gpu/command_buffer/client/gles2_interface.h"
18 #include "gpu/ipc/client/gpu_channel_host.h"
19
20 namespace content {
21
22 base::LazyInstance<scoped_refptr<cc::VulkanInProcessContextProvider>>
23 g_shared_vulkan_context_provider_android = LAZY_INSTANCE_INITIALIZER;
24
25 // static
26 ContextProviderFactoryImpl* ContextProviderFactoryImpl::GetInstance() {
27 return base::Singleton<ContextProviderFactoryImpl>::get();
28 }
29
30 ContextProviderFactoryImpl::ContextProviderFactoryImpl()
31 : in_handle_pending_requests_(false), weak_factory_(this) {}
32
33 ContextProviderFactoryImpl::~ContextProviderFactoryImpl() {}
34
35 void ContextProviderFactoryImpl::RequestRenderContextProvider(
36 ContextProviderCallback result_callback) {
37 render_context_request_callbacks_.push_back(result_callback);
38
39 HandlePendingRequests();
40 }
41
42 void ContextProviderFactoryImpl::RequestGpuChannel(
43 GpuChannelRequestCallback gpu_channel_request_callback) {
44 gpu_channel_request_callback_ = gpu_channel_request_callback;
45
46 HandlePendingRequests();
47 }
48
49 scoped_refptr<cc::VulkanInProcessContextProvider>
50 ContextProviderFactoryImpl::GetSharedVulkanContextProviderAndroid() {
51 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
52 switches::kEnableVulkan)) {
53 scoped_refptr<cc::VulkanInProcessContextProvider>* context_provider =
54 g_shared_vulkan_context_provider_android.Pointer();
55 if (!*context_provider)
56 *context_provider = cc::VulkanInProcessContextProvider::Create();
57 return *context_provider;
58 }
59 return nullptr;
60 }
61
62 void ContextProviderFactoryImpl::HandlePendingRequests() {
63 // Failure to initialize the context could result in new requests. Handle
64 // them after going through the current list.
65 if (in_handle_pending_requests_)
66 return;
67
68 {
69 base::AutoReset<bool> auto_reset_in_handle_requests(
70 &in_handle_pending_requests_, true);
71
72 scoped_refptr<cc::VulkanInProcessContextProvider> vulkan_context_provider =
73 GetSharedVulkanContextProviderAndroid();
74
75 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host(
76 vulkan_context_provider ? nullptr : EnsureGpuChannelEstablished());
77
78 if (!vulkan_context_provider && !gpu_channel_host)
79 return;
80
81 if (!render_context_request_callbacks_.empty()) {
82 std::list<ContextProviderCallback> context_requests =
83 render_context_request_callbacks_;
84 render_context_request_callbacks_.clear();
85
86 for (ContextProviderCallback& context_request : context_requests) {
87 ContextProviders context_providers;
88
89 if (vulkan_context_provider)
90 context_providers.vulkan_context_provider = vulkan_context_provider;
91 else
92 CreateRenderCompositorContexts(context_providers, gpu_channel_host);
93
94 context_request.Run(context_providers);
95 }
96 }
97
98 if (!gpu_channel_request_callback_.is_null()) {
99 if (!gpu_channel_host)
100 gpu_channel_host = EnsureGpuChannelEstablished();
101
102 if (!gpu_channel_host)
103 return;
104
105 GpuChannelRequestCallback gpu_request_callback =
106 gpu_channel_request_callback_;
107 gpu_channel_request_callback_ = GpuChannelRequestCallback();
108 gpu_request_callback.Run(gpu_channel_host);
109 }
110 }
111
112 if (!gpu_channel_request_callback_.is_null() ||
113 !render_context_request_callbacks_.empty())
114 HandlePendingRequests();
115 }
116
117 void ContextProviderFactoryImpl::CreateRenderCompositorContexts(
118 ContextProviders& context_providers,
119 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) {
120 DCHECK(gpu_channel_host);
121
122 // TODO(khushalsagar): Figure out if we can share this code with the
123 // renderer compositor.
124 scoped_refptr<ContextProviderCommandBuffer> worker_context_provider =
125 SharedCompositorWorkerContextProvider(gpu_channel_host);
126 if (!worker_context_provider) {
127 // Cause the compositor to wait and try again.
128 return;
129 }
130
131 // The renderer compositor context doesn't do a lot of stuff, so we don't
132 // expect it to need a lot of space for commands or transfer. Raster and
133 // uploads happen on the worker context instead.
134 gpu::SharedMemoryLimits limits = gpu::SharedMemoryLimits::ForMailboxContext();
135
136 // This is for an offscreen context for the compositor. So the default
137 // framebuffer doesn't need alpha, depth, stencil, antialiasing.
138 gpu::gles2::ContextCreationAttribHelper attributes;
139 attributes.alpha_size = -1;
140 attributes.depth_size = 0;
141 attributes.stencil_size = 0;
142 attributes.samples = 0;
143 attributes.sample_buffers = 0;
144 attributes.bind_generates_resource = false;
145 attributes.lose_context_when_out_of_memory = true;
146
147 constexpr bool automatic_flushes = false;
148 constexpr bool support_locking = false;
149
150 // The compositor context shares resources with the worker context unless
151 // the worker is async.
152 ContextProviderCommandBuffer* share_context = worker_context_provider.get();
153 if (IsAsyncWorkerContextEnabled())
154 share_context = nullptr;
155
156 scoped_refptr<ContextProviderCommandBuffer> context_provider(
157 new ContextProviderCommandBuffer(
158 gpu_channel_host, gpu::GPU_STREAM_DEFAULT,
159 gpu::GpuStreamPriority::NORMAL, gpu::kNullSurfaceHandle,
160 GURL(std::string("chrome://gpu/ContextProviderFactoryImpl::") +
161 std::string("CompositorContextProvider")),
162 automatic_flushes, support_locking, limits, attributes, share_context,
163 command_buffer_metrics::RENDER_COMPOSITOR_CONTEXT));
164
165 context_providers.compositor_context_provider = std::move(context_provider);
166 context_providers.worker_context_provider =
167 std::move(worker_context_provider);
168 }
169
170 scoped_refptr<ContextProviderCommandBuffer>
171 ContextProviderFactoryImpl::SharedCompositorWorkerContextProvider(
172 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) {
173 // Try to reuse existing shared worker context provider.
174 if (shared_worker_context_provider_) {
175 // Note: If context is lost, delete reference after releasing the lock.
176 cc::ContextProvider::ScopedContextLock lock(
177 shared_worker_context_provider_.get());
178 if (shared_worker_context_provider_->ContextGL()
179 ->GetGraphicsResetStatusKHR() == GL_NO_ERROR)
180 return shared_worker_context_provider_;
181 }
182
183 int32_t stream_id = gpu::GPU_STREAM_DEFAULT;
184 gpu::GpuStreamPriority stream_priority = gpu::GpuStreamPriority::NORMAL;
185 if (IsAsyncWorkerContextEnabled()) {
186 stream_id = gpu_channel_host->GenerateStreamID();
187 stream_priority = gpu::GpuStreamPriority::LOW;
188 }
189
190 bool support_locking = true;
191 gpu::gles2::ContextCreationAttribHelper attributes;
192 attributes.alpha_size = -1;
193 attributes.depth_size = 0;
194 attributes.stencil_size = 0;
195 attributes.samples = 0;
196 attributes.sample_buffers = 0;
197 attributes.bind_generates_resource = false;
198 attributes.lose_context_when_out_of_memory = true;
199 const bool automatic_flushes = false;
200
201 shared_worker_context_provider_ = new ContextProviderCommandBuffer(
202 std::move(gpu_channel_host), stream_id, stream_priority,
203 gpu::kNullSurfaceHandle,
204 GURL(std::string("chrome://gpu/ContextProviderFactoryImpl::") +
205 std::string("SharedCompositorWorkerContextProvider")),
206 automatic_flushes, support_locking, gpu::SharedMemoryLimits(), attributes,
207 nullptr, command_buffer_metrics::RENDER_WORKER_CONTEXT);
208
209 if (!shared_worker_context_provider_->BindToCurrentThread())
210 shared_worker_context_provider_ = nullptr;
211 return shared_worker_context_provider_;
212 }
213
214 gpu::GpuChannelHost* ContextProviderFactoryImpl::EnsureGpuChannelEstablished() {
215 #if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
216 defined(SYZYASAN) || defined(CYGPROFILE_INSTRUMENTATION)
217 const int64_t kGpuChannelTimeoutInSeconds = 40;
218 #else
219 const int64_t kGpuChannelTimeoutInSeconds = 10;
220 #endif
221
222 BrowserGpuChannelHostFactory* factory =
223 BrowserGpuChannelHostFactory::instance();
224
225 if (factory->GetGpuChannel())
226 return factory->GetGpuChannel();
227
228 factory->EstablishGpuChannel(
229 CAUSE_FOR_GPU_LAUNCH_DISPLAY_COMPOSITOR_CONTEXT,
230 base::Bind(&ContextProviderFactoryImpl::OnGpuChannelEstablished,
231 weak_factory_.GetWeakPtr()));
232 establish_gpu_channel_timeout_.Start(
233 FROM_HERE, base::TimeDelta::FromSeconds(kGpuChannelTimeoutInSeconds),
234 this, &ContextProviderFactoryImpl::OnGpuChannelTimeout);
235
236 return nullptr;
237 }
238
239 void ContextProviderFactoryImpl::OnGpuChannelEstablished() {
240 establish_gpu_channel_timeout_.Stop();
241 HandlePendingRequests();
242 }
243
244 void ContextProviderFactoryImpl::OnGpuChannelTimeout() {
245 LOG(FATAL) << "Timed out waiting for GPU channel.";
246 }
247
248 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698