blob: 2826274beda9a0877a1690430020156bc89e2dd7 [file] [log] [blame]
Mohsen Izadi0b9fbb62018-08-30 20:30:001// Copyright 2018 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 "components/viz/host/gpu_host_impl.h"
6
7#include <utility>
8
Sebastien Marchand53801a32019-01-25 16:26:119#include "base/bind.h"
Mohsen Izadi0b9fbb62018-08-30 20:30:0010#include "base/bind_helpers.h"
Mohsen Izadi0b9fbb62018-08-30 20:30:0011#include "base/feature_list.h"
12#include "base/metrics/histogram_macros.h"
13#include "base/no_destructor.h"
14#include "base/threading/thread_checker.h"
Mohsen Izadi63d85e72018-09-06 16:00:2115#include "base/threading/thread_task_runner_handle.h"
Mohsen Izadi0b9fbb62018-08-30 20:30:0016#include "base/trace_event/trace_event.h"
17#include "build/build_config.h"
18#include "components/viz/common/features.h"
19#include "gpu/config/gpu_driver_bug_workaround_type.h"
Jonah Ryan-Davisa70577c2019-06-26 18:54:3120#include "gpu/config/gpu_extra_info.h"
Mohsen Izadi0b9fbb62018-08-30 20:30:0021#include "gpu/config/gpu_feature_info.h"
22#include "gpu/config/gpu_finch_features.h"
23#include "gpu/config/gpu_info.h"
24#include "gpu/ipc/common/gpu_client_ids.h"
25#include "gpu/ipc/host/shader_disk_cache.h"
Mohsen Izadi63d85e72018-09-06 16:00:2126#include "ui/base/ui_base_features.h"
Mohsen Izadi0b9fbb62018-08-30 20:30:0027#include "ui/gfx/font_render_params.h"
Mohsen Izadi63d85e72018-09-06 16:00:2128#include "ui/ozone/public/gpu_platform_support_host.h"
29#include "ui/ozone/public/ozone_platform.h"
Mohsen Izadi0b9fbb62018-08-30 20:30:0030
31#if defined(OS_ANDROID)
32#include "base/android/build_info.h"
33#endif
34
35#if defined(OS_WIN)
36#include "ui/gfx/win/rendering_window_manager.h"
37#endif
38
39namespace viz {
40namespace {
41
42// A wrapper around gfx::FontRenderParams that checks it is set and accessed on
43// the same thread.
44class FontRenderParams {
45 public:
46 void Set(const gfx::FontRenderParams& params);
Mohsen Izadif9505d82018-10-06 01:34:0347 void Reset();
Mohsen Izadi0b9fbb62018-08-30 20:30:0048 const base::Optional<gfx::FontRenderParams>& Get();
49
50 private:
51 friend class base::NoDestructor<FontRenderParams>;
52
53 FontRenderParams();
54 ~FontRenderParams();
55
56 THREAD_CHECKER(thread_checker_);
57 base::Optional<gfx::FontRenderParams> params_;
58
59 DISALLOW_COPY_AND_ASSIGN(FontRenderParams);
60};
61
62void FontRenderParams::Set(const gfx::FontRenderParams& params) {
63 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
64 params_ = params;
65}
66
Mohsen Izadif9505d82018-10-06 01:34:0367void FontRenderParams::Reset() {
68 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
69 params_ = base::nullopt;
70}
71
Mohsen Izadi0b9fbb62018-08-30 20:30:0072const base::Optional<gfx::FontRenderParams>& FontRenderParams::Get() {
73 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
74 return params_;
75}
76
77FontRenderParams::FontRenderParams() = default;
78
79FontRenderParams::~FontRenderParams() {
80 NOTREACHED();
81}
82
83FontRenderParams& GetFontRenderParams() {
84 static base::NoDestructor<FontRenderParams> instance;
85 return *instance;
86}
87
88} // namespace
89
90GpuHostImpl::InitParams::InitParams() = default;
91
92GpuHostImpl::InitParams::InitParams(InitParams&&) = default;
93
94GpuHostImpl::InitParams::~InitParams() = default;
95
96GpuHostImpl::GpuHostImpl(Delegate* delegate,
kylechar80dd2aa2019-07-22 15:31:3997 mojo::PendingAssociatedRemote<mojom::VizMain> viz_main,
Mohsen Izadi0b9fbb62018-08-30 20:30:0098 InitParams params)
99 : delegate_(delegate),
kylechar80dd2aa2019-07-22 15:31:39100 viz_main_(std::move(viz_main)),
Mohsen Izadi0b9fbb62018-08-30 20:30:00101 params_(std::move(params)),
Shimi Zhang88ae9222019-07-19 16:54:16102 host_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
Mohsen Izadi0b9fbb62018-08-30 20:30:00103 DCHECK(delegate_);
Mohsen Izadi0b9fbb62018-08-30 20:30:00104
Julie Jeongeun Kim7b4a6aa12019-09-20 14:57:12105 mojo::PendingRemote<discardable_memory::mojom::DiscardableSharedMemoryManager>
106 discardable_manager_remote;
107 delegate_->BindDiscardableMemoryReceiver(
108 discardable_manager_remote.InitWithNewPipeAndPassReceiver());
Mohsen Izadi0b9fbb62018-08-30 20:30:00109
110 DCHECK(GetFontRenderParams().Get());
kylechar80dd2aa2019-07-22 15:31:39111 viz_main_->CreateGpuService(gpu_service_remote_.BindNewPipeAndPassReceiver(),
112 gpu_host_receiver_.BindNewPipeAndPassRemote(),
Julie Jeongeun Kim7b4a6aa12019-09-20 14:57:12113 std::move(discardable_manager_remote),
kylechar80dd2aa2019-07-22 15:31:39114 activity_flags_.CloneHandle(),
115 GetFontRenderParams().Get()->subpixel_rendering);
Mohsen Izadi63d85e72018-09-06 16:00:21116
117#if defined(USE_OZONE)
118 InitOzone();
119#endif // defined(USE_OZONE)
Mohsen Izadi0b9fbb62018-08-30 20:30:00120}
121
Mohsen Izadif9505d82018-10-06 01:34:03122GpuHostImpl::~GpuHostImpl() {
123 SendOutstandingReplies();
124}
Mohsen Izadi0b9fbb62018-08-30 20:30:00125
126// static
127void GpuHostImpl::InitFontRenderParams(const gfx::FontRenderParams& params) {
128 DCHECK(!GetFontRenderParams().Get());
129 GetFontRenderParams().Set(params);
130}
131
Mohsen Izadif9505d82018-10-06 01:34:03132// static
133void GpuHostImpl::ResetFontRenderParams() {
134 DCHECK(GetFontRenderParams().Get());
135 GetFontRenderParams().Reset();
136}
137
kylechar9b37f172019-09-19 22:55:27138void GpuHostImpl::SetProcessId(base::ProcessId pid) {
Mohsen Izadi0b9fbb62018-08-30 20:30:00139 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
140 DCHECK_EQ(base::kNullProcessId, pid_);
141 DCHECK_NE(base::kNullProcessId, pid);
142 pid_ = pid;
143}
144
145void GpuHostImpl::OnProcessCrashed() {
146 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
147
148 // If the GPU process crashed while compiling a shader, we may have invalid
149 // cached binaries. Completely clear the shader cache to force shader binaries
150 // to be re-created.
151 if (activity_flags_.IsFlagSet(
152 gpu::ActivityFlagsBase::FLAG_LOADING_PROGRAM_BINARY)) {
153 auto* shader_cache_factory = delegate_->GetShaderCacheFactory();
154 for (auto cache_key : client_id_to_shader_cache_) {
155 // This call will temporarily extend the lifetime of the cache (kept
156 // alive in the factory), and may drop loads of cached shader binaries if
157 // it takes a while to complete. As we are intentionally dropping all
158 // binaries, this behavior is fine.
159 shader_cache_factory->ClearByClientId(
160 cache_key.first, base::Time(), base::Time::Max(), base::DoNothing());
161 }
162 }
163}
164
Mohsen Izadibabed2b2018-08-31 01:37:39165void GpuHostImpl::AddConnectionErrorHandler(base::OnceClosure handler) {
166 connection_error_handlers_.push_back(std::move(handler));
167}
168
Mohsen Izadi0b9fbb62018-08-30 20:30:00169void GpuHostImpl::BlockLiveOffscreenContexts() {
170 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
171
172 for (auto iter = urls_with_live_offscreen_contexts_.begin();
173 iter != urls_with_live_offscreen_contexts_.end(); ++iter) {
Mohsen Izadi312c6922018-09-07 14:21:36174 delegate_->BlockDomainFrom3DAPIs(*iter, gpu::DomainGuilt::kUnknown);
Mohsen Izadi0b9fbb62018-08-30 20:30:00175 }
176}
177
178void GpuHostImpl::ConnectFrameSinkManager(
Mario Sanchez Prada745dd5e2019-10-16 14:14:30179 mojo::PendingReceiver<mojom::FrameSinkManager> receiver,
Mario Sanchez Pradaa0e3c3a12019-10-16 17:26:35180 mojo::PendingRemote<mojom::FrameSinkManagerClient> client) {
Mohsen Izadi0b9fbb62018-08-30 20:30:00181 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
182 TRACE_EVENT0("gpu", "GpuHostImpl::ConnectFrameSinkManager");
183
184 mojom::FrameSinkManagerParamsPtr params =
185 mojom::FrameSinkManagerParams::New();
186 params->restart_id = params_.restart_id;
187 params->use_activation_deadline =
188 params_.deadline_to_synchronize_surfaces.has_value();
189 params->activation_deadline_in_frames =
190 params_.deadline_to_synchronize_surfaces.value_or(0u);
Mario Sanchez Prada745dd5e2019-10-16 14:14:30191 params->frame_sink_manager = std::move(receiver);
Mohsen Izadi0b9fbb62018-08-30 20:30:00192 params->frame_sink_manager_client = std::move(client);
kylechar80dd2aa2019-07-22 15:31:39193 viz_main_->CreateFrameSinkManager(std::move(params));
Mohsen Izadi0b9fbb62018-08-30 20:30:00194}
195
Robert Seseka9b47c92019-08-30 01:22:54196#if BUILDFLAG(USE_VIZ_DEVTOOLS)
Sean Gilhulyda1ee4b2018-11-13 21:56:09197void GpuHostImpl::ConnectVizDevTools(mojom::VizDevToolsParamsPtr params) {
kylechar80dd2aa2019-07-22 15:31:39198 viz_main_->CreateVizDevTools(std::move(params));
Sean Gilhulyda1ee4b2018-11-13 21:56:09199}
200#endif
201
Mohsen Izadi0b9fbb62018-08-30 20:30:00202void GpuHostImpl::EstablishGpuChannel(int client_id,
203 uint64_t client_tracing_id,
204 bool is_gpu_host,
205 EstablishChannelCallback callback) {
206 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
207 TRACE_EVENT0("gpu", "GpuHostImpl::EstablishGpuChannel");
208
Bo Liu95570f32020-03-16 23:42:17209 shutdown_timeout_.Stop();
210
Mohsen Izadi0b9fbb62018-08-30 20:30:00211 // If GPU features are already blacklisted, no need to establish the channel.
212 if (!delegate_->GpuAccessAllowed()) {
213 DVLOG(1) << "GPU blacklisted, refusing to open a GPU channel.";
214 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
215 gpu::GpuFeatureInfo(),
216 EstablishChannelStatus::kGpuAccessDenied);
217 return;
218 }
219
220 if (gpu::IsReservedClientId(client_id)) {
221 // The display-compositor/GrShaderCache in the gpu process uses these
222 // special client ids.
223 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
224 gpu::GpuFeatureInfo(),
225 EstablishChannelStatus::kGpuAccessDenied);
226 return;
227 }
228
229 bool cache_shaders_on_disk =
230 delegate_->GetShaderCacheFactory()->Get(client_id) != nullptr;
231
232 channel_requests_.push(std::move(callback));
Shimi Zhang88ae9222019-07-19 16:54:16233 gpu_service_remote_->EstablishGpuChannel(
Mohsen Izadi0b9fbb62018-08-30 20:30:00234 client_id, client_tracing_id, is_gpu_host, cache_shaders_on_disk,
235 base::BindOnce(&GpuHostImpl::OnChannelEstablished,
236 weak_ptr_factory_.GetWeakPtr(), client_id));
237
Jonathan Backer06c419e12019-01-22 14:37:14238 if (!params_.disable_gpu_shader_disk_cache)
Mohsen Izadi0b9fbb62018-08-30 20:30:00239 CreateChannelCache(client_id);
Mohsen Izadi0b9fbb62018-08-30 20:30:00240}
241
242void GpuHostImpl::SendOutstandingReplies() {
243 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
244
Mohsen Izadibabed2b2018-08-31 01:37:39245 for (auto& handler : connection_error_handlers_)
246 std::move(handler).Run();
247 connection_error_handlers_.clear();
248
Mohsen Izadi0b9fbb62018-08-30 20:30:00249 // Send empty channel handles for all EstablishChannel requests.
250 while (!channel_requests_.empty()) {
251 auto callback = std::move(channel_requests_.front());
252 channel_requests_.pop();
253 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
254 gpu::GpuFeatureInfo(),
255 EstablishChannelStatus::kGpuHostInvalid);
256 }
257}
258
Mohsen Izadi63d85e72018-09-06 16:00:21259void GpuHostImpl::BindInterface(const std::string& interface_name,
260 mojo::ScopedMessagePipeHandle interface_pipe) {
261 delegate_->BindInterface(interface_name, std::move(interface_pipe));
262}
263
Ken Rockotb2928f32019-03-12 04:43:03264void GpuHostImpl::RunService(
265 const std::string& service_name,
266 mojo::PendingReceiver<service_manager::mojom::Service> receiver) {
267 delegate_->RunService(service_name, std::move(receiver));
268}
269
Mohsen Izadi0b9fbb62018-08-30 20:30:00270mojom::GpuService* GpuHostImpl::gpu_service() {
271 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Shimi Zhang88ae9222019-07-19 16:54:16272 DCHECK(gpu_service_remote_.is_bound());
273 return gpu_service_remote_.get();
Mohsen Izadi0b9fbb62018-08-30 20:30:00274}
275
Mohsen Izadi63d85e72018-09-06 16:00:21276#if defined(USE_OZONE)
Mohsen Izadia378a8f42019-08-02 02:34:19277
Mohsen Izadi63d85e72018-09-06 16:00:21278void GpuHostImpl::InitOzone() {
279 // Ozone needs to send the primary DRM device to GPU service as early as
280 // possible to ensure the latter always has a valid device.
281 // https://crbug.com/608839
Maksim Sisov2e064342018-10-03 10:35:06282 //
283 // The Ozone/Wayland requires mojo communication to be established to be
284 // functional with a separate gpu process. Thus, using the PlatformProperties,
285 // check if there is such a requirement.
Kramer Gec78fde4e2020-04-18 18:58:06286 auto interface_binder = base::BindRepeating(&GpuHostImpl::BindInterface,
287 weak_ptr_factory_.GetWeakPtr());
288 auto terminate_callback = base::BindOnce(&GpuHostImpl::TerminateGpuProcess,
289 weak_ptr_factory_.GetWeakPtr());
Mohsen Izadi63d85e72018-09-06 16:00:21290
Kramer Gec78fde4e2020-04-18 18:58:06291 ui::OzonePlatform::GetInstance()
292 ->GetGpuPlatformSupportHost()
293 ->OnGpuServiceLaunched(params_.restart_id,
294 params_.main_thread_task_runner,
295 host_thread_task_runner_, interface_binder,
296 std::move(terminate_callback));
Mohsen Izadi63d85e72018-09-06 16:00:21297}
298
299void GpuHostImpl::TerminateGpuProcess(const std::string& message) {
300 delegate_->TerminateGpuProcess(message);
301}
302
303#endif // defined(USE_OZONE)
304
Mohsen Izadi0b9fbb62018-08-30 20:30:00305std::string GpuHostImpl::GetShaderPrefixKey() {
306 if (shader_prefix_key_.empty()) {
307 const gpu::GPUInfo& info = delegate_->GetGPUInfo();
308 const gpu::GPUInfo::GPUDevice& active_gpu = info.active_gpu();
309
310 shader_prefix_key_ = params_.product + "-" + info.gl_vendor + "-" +
311 info.gl_renderer + "-" + active_gpu.driver_version +
312 "-" + active_gpu.driver_vendor;
313
314#if defined(OS_ANDROID)
315 std::string build_fp =
316 base::android::BuildInfo::GetInstance()->android_build_fp();
Mohsen Izadi0b9fbb62018-08-30 20:30:00317 shader_prefix_key_ += "-" + build_fp;
318#endif
319 }
320
321 return shader_prefix_key_;
322}
323
324void GpuHostImpl::LoadedShader(int32_t client_id,
325 const std::string& key,
326 const std::string& data) {
327 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
328
329 std::string prefix = GetShaderPrefixKey();
330 bool prefix_ok = !key.compare(0, prefix.length(), prefix);
331 UMA_HISTOGRAM_BOOLEAN("GPU.ShaderLoadPrefixOK", prefix_ok);
332 if (prefix_ok) {
333 // Remove the prefix from the key before load.
334 std::string key_no_prefix = key.substr(prefix.length() + 1);
Shimi Zhang88ae9222019-07-19 16:54:16335 gpu_service_remote_->LoadedShader(client_id, key_no_prefix, data);
Mohsen Izadi0b9fbb62018-08-30 20:30:00336 }
337}
338
339void GpuHostImpl::CreateChannelCache(int32_t client_id) {
340 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
341 TRACE_EVENT0("gpu", "GpuHostImpl::CreateChannelCache");
342
343 scoped_refptr<gpu::ShaderDiskCache> cache =
344 delegate_->GetShaderCacheFactory()->Get(client_id);
345 if (!cache)
346 return;
347
348 cache->set_shader_loaded_callback(base::BindRepeating(
349 &GpuHostImpl::LoadedShader, weak_ptr_factory_.GetWeakPtr(), client_id));
350
351 client_id_to_shader_cache_[client_id] = cache;
352}
353
354void GpuHostImpl::OnChannelEstablished(
355 int client_id,
356 mojo::ScopedMessagePipeHandle channel_handle) {
357 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
358 TRACE_EVENT0("gpu", "GpuHostImpl::OnChannelEstablished");
359
360 DCHECK(!channel_requests_.empty());
361 auto callback = std::move(channel_requests_.front());
362 channel_requests_.pop();
363
364 // Currently if any of the GPU features are blacklisted, we don't establish a
365 // GPU channel.
366 if (channel_handle.is_valid() && !delegate_->GpuAccessAllowed()) {
Shimi Zhang88ae9222019-07-19 16:54:16367 gpu_service_remote_->CloseChannel(client_id);
Mohsen Izadi0b9fbb62018-08-30 20:30:00368 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
369 gpu::GpuFeatureInfo(),
370 EstablishChannelStatus::kGpuAccessDenied);
371 RecordLogMessage(logging::LOG_WARNING, "WARNING",
372 "Hardware acceleration is unavailable.");
373 return;
374 }
375
376 std::move(callback).Run(std::move(channel_handle), delegate_->GetGPUInfo(),
377 delegate_->GetGpuFeatureInfo(),
378 EstablishChannelStatus::kSuccess);
379}
380
381void GpuHostImpl::DidInitialize(
382 const gpu::GPUInfo& gpu_info,
383 const gpu::GpuFeatureInfo& gpu_feature_info,
384 const base::Optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu,
385 const base::Optional<gpu::GpuFeatureInfo>&
Jonah Ryan-Davisa70577c2019-06-26 18:54:31386 gpu_feature_info_for_hardware_gpu,
387 const gpu::GpuExtraInfo& gpu_extra_info) {
Mohsen Izadi0b9fbb62018-08-30 20:30:00388 UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", true);
Mohsen Izadi0b9fbb62018-08-30 20:30:00389
390 // Set GPU driver bug workaround flags that are checked on the browser side.
391 wake_up_gpu_before_drawing_ =
392 gpu_feature_info.IsWorkaroundEnabled(gpu::WAKE_UP_GPU_BEFORE_DRAWING);
393 dont_disable_webgl_when_compositor_context_lost_ =
394 gpu_feature_info.IsWorkaroundEnabled(
395 gpu::DONT_DISABLE_WEBGL_WHEN_COMPOSITOR_CONTEXT_LOST);
396
Mohsen Izadif9505d82018-10-06 01:34:03397 delegate_->DidInitialize(gpu_info, gpu_feature_info,
Mohsen Izadi0b9fbb62018-08-30 20:30:00398 gpu_info_for_hardware_gpu,
Jonah Ryan-Davisa70577c2019-06-26 18:54:31399 gpu_feature_info_for_hardware_gpu, gpu_extra_info);
Jonathan Backer06c419e12019-01-22 14:37:14400
401 if (!params_.disable_gpu_shader_disk_cache) {
kylecharae6f3132019-12-18 18:25:14402 CreateChannelCache(gpu::kInProcessCommandBufferClientId);
Jonathan Backer06c419e12019-01-22 14:37:14403
Peng Huang70021682019-09-18 19:42:28404 bool use_gr_shader_cache = base::FeatureList::IsEnabled(
405 features::kDefaultEnableOopRasterization) ||
406 features::IsUsingSkiaRenderer();
Jonathan Backer06c419e12019-01-22 14:37:14407 if (use_gr_shader_cache)
408 CreateChannelCache(gpu::kGrShaderCacheClientId);
409 }
Mohsen Izadi0b9fbb62018-08-30 20:30:00410}
411
412void GpuHostImpl::DidFailInitialize() {
413 UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", false);
414 delegate_->DidFailInitialize();
415}
416
417void GpuHostImpl::DidCreateContextSuccessfully() {
418 delegate_->DidCreateContextSuccessfully();
419}
420
421void GpuHostImpl::DidCreateOffscreenContext(const GURL& url) {
422 urls_with_live_offscreen_contexts_.insert(url);
423}
424
425void GpuHostImpl::DidDestroyOffscreenContext(const GURL& url) {
426 // We only want to remove *one* of the entries in the multiset for this
427 // particular URL, so can't use the erase method taking a key.
428 auto candidate = urls_with_live_offscreen_contexts_.find(url);
429 if (candidate != urls_with_live_offscreen_contexts_.end())
430 urls_with_live_offscreen_contexts_.erase(candidate);
431}
432
433void GpuHostImpl::DidDestroyChannel(int32_t client_id) {
434 TRACE_EVENT0("gpu", "GpuHostImpl::DidDestroyChannel");
435 client_id_to_shader_cache_.erase(client_id);
436}
437
Bo Liu95570f32020-03-16 23:42:17438void GpuHostImpl::DidDestroyAllChannels() {
439 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
440 if (!channel_requests_.empty())
441 return;
442 constexpr base::TimeDelta kShutDownTimeout = base::TimeDelta::FromSeconds(10);
443 shutdown_timeout_.Start(FROM_HERE, kShutDownTimeout,
444 base::BindOnce(&GpuHostImpl::MaybeShutdownGpuProcess,
445 base::Unretained(this)));
446}
447
448void GpuHostImpl::MaybeShutdownGpuProcess() {
449 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
450 DCHECK(channel_requests_.empty());
451 delegate_->MaybeShutdownGpuProcess();
452}
453
Mohsen Izadi0b9fbb62018-08-30 20:30:00454void GpuHostImpl::DidLoseContext(bool offscreen,
455 gpu::error::ContextLostReason reason,
456 const GURL& active_url) {
457 // TODO(kbr): would be nice to see the "offscreen" flag too.
458 TRACE_EVENT2("gpu", "GpuHostImpl::DidLoseContext", "reason", reason, "url",
459 active_url.possibly_invalid_spec());
460
461 if (!offscreen || active_url.is_empty()) {
462 // Assume that the loss of the compositor's or accelerated canvas'
463 // context is a serious event and blame the loss on all live
464 // offscreen contexts. This more robustly handles situations where
465 // the GPU process may not actually detect the context loss in the
466 // offscreen context. However, situations have been seen where the
467 // compositor's context can be lost due to driver bugs (as of this
468 // writing, on Android), so allow that possibility.
469 if (!dont_disable_webgl_when_compositor_context_lost_)
470 BlockLiveOffscreenContexts();
471 return;
472 }
473
Mohsen Izadi312c6922018-09-07 14:21:36474 gpu::DomainGuilt guilt = gpu::DomainGuilt::kUnknown;
Mohsen Izadi0b9fbb62018-08-30 20:30:00475 switch (reason) {
476 case gpu::error::kGuilty:
Mohsen Izadi312c6922018-09-07 14:21:36477 guilt = gpu::DomainGuilt::kKnown;
Mohsen Izadi0b9fbb62018-08-30 20:30:00478 break;
479 // Treat most other error codes as though they had unknown provenance.
480 // In practice this doesn't affect the user experience. A lost context
481 // of either known or unknown guilt still causes user-level 3D APIs
482 // (e.g. WebGL) to be blocked on that domain until the user manually
483 // reenables them.
484 case gpu::error::kUnknown:
485 case gpu::error::kOutOfMemory:
486 case gpu::error::kMakeCurrentFailed:
487 case gpu::error::kGpuChannelLost:
488 case gpu::error::kInvalidGpuMessage:
489 break;
490 case gpu::error::kInnocent:
491 return;
492 }
493
494 delegate_->BlockDomainFrom3DAPIs(active_url, guilt);
495}
496
497void GpuHostImpl::DisableGpuCompositing() {
498 delegate_->DisableGpuCompositing();
499}
500
Mohsen Izadi50c28052018-09-07 00:32:14501#if defined(OS_WIN)
Maggie Chen8f177172020-02-11 00:02:28502void GpuHostImpl::DidUpdateOverlayInfo(const gpu::OverlayInfo& overlay_info) {
503 delegate_->DidUpdateOverlayInfo(overlay_info);
504}
505
Mohsen Izadi0b9fbb62018-08-30 20:30:00506void GpuHostImpl::SetChildSurface(gpu::SurfaceHandle parent,
507 gpu::SurfaceHandle child) {
kylechar89341da82018-09-10 15:26:27508 if (pid_ != base::kNullProcessId) {
509 gfx::RenderingWindowManager::GetInstance()->RegisterChild(
510 parent, child, /*expected_child_process_id=*/pid_);
Mohsen Izadi0b9fbb62018-08-30 20:30:00511 }
Mohsen Izadi0b9fbb62018-08-30 20:30:00512}
Mohsen Izadi50c28052018-09-07 00:32:14513#endif // defined(OS_WIN)
Mohsen Izadi0b9fbb62018-08-30 20:30:00514
515void GpuHostImpl::StoreShaderToDisk(int32_t client_id,
516 const std::string& key,
517 const std::string& shader) {
518 TRACE_EVENT0("gpu", "GpuHostImpl::StoreShaderToDisk");
519 auto iter = client_id_to_shader_cache_.find(client_id);
520 // If the cache doesn't exist then this is an off the record profile.
521 if (iter == client_id_to_shader_cache_.end())
522 return;
523 std::string prefix = GetShaderPrefixKey();
524 iter->second->Cache(prefix + ":" + key, shader);
525}
526
527void GpuHostImpl::RecordLogMessage(int32_t severity,
528 const std::string& header,
529 const std::string& message) {
530 delegate_->RecordLogMessage(severity, header, message);
531}
532
533} // namespace viz