blob: 2765f02e86db903d6c39c3c955e5bc791a7946f4 [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"
28
29#if defined(OS_ANDROID)
30#include "base/android/build_info.h"
31#endif
32
33#if defined(OS_WIN)
34#include "ui/gfx/win/rendering_window_manager.h"
35#endif
36
Maksim Sisov4f5918f2020-06-24 08:26:0037#if defined(USE_OZONE)
Peng Huang2d5cf682020-07-31 14:07:4738#include "ui/ozone/public/gpu_platform_support_host.h"
39#include "ui/ozone/public/ozone_platform.h"
Maksim Sisov4f5918f2020-06-24 08:26:0040#endif
41
Mohsen Izadi0b9fbb62018-08-30 20:30:0042namespace viz {
43namespace {
44
45// A wrapper around gfx::FontRenderParams that checks it is set and accessed on
46// the same thread.
47class FontRenderParams {
48 public:
49 void Set(const gfx::FontRenderParams& params);
Mohsen Izadif9505d82018-10-06 01:34:0350 void Reset();
Mohsen Izadi0b9fbb62018-08-30 20:30:0051 const base::Optional<gfx::FontRenderParams>& Get();
52
53 private:
54 friend class base::NoDestructor<FontRenderParams>;
55
56 FontRenderParams();
57 ~FontRenderParams();
58
59 THREAD_CHECKER(thread_checker_);
60 base::Optional<gfx::FontRenderParams> params_;
61
62 DISALLOW_COPY_AND_ASSIGN(FontRenderParams);
63};
64
65void FontRenderParams::Set(const gfx::FontRenderParams& params) {
66 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
67 params_ = params;
68}
69
Mohsen Izadif9505d82018-10-06 01:34:0370void FontRenderParams::Reset() {
71 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
72 params_ = base::nullopt;
73}
74
Mohsen Izadi0b9fbb62018-08-30 20:30:0075const base::Optional<gfx::FontRenderParams>& FontRenderParams::Get() {
76 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
77 return params_;
78}
79
80FontRenderParams::FontRenderParams() = default;
81
82FontRenderParams::~FontRenderParams() {
83 NOTREACHED();
84}
85
86FontRenderParams& GetFontRenderParams() {
87 static base::NoDestructor<FontRenderParams> instance;
88 return *instance;
89}
90
91} // namespace
92
93GpuHostImpl::InitParams::InitParams() = default;
94
95GpuHostImpl::InitParams::InitParams(InitParams&&) = default;
96
97GpuHostImpl::InitParams::~InitParams() = default;
98
99GpuHostImpl::GpuHostImpl(Delegate* delegate,
kylechar80dd2aa2019-07-22 15:31:39100 mojo::PendingAssociatedRemote<mojom::VizMain> viz_main,
Mohsen Izadi0b9fbb62018-08-30 20:30:00101 InitParams params)
102 : delegate_(delegate),
kylechar80dd2aa2019-07-22 15:31:39103 viz_main_(std::move(viz_main)),
Mohsen Izadi0b9fbb62018-08-30 20:30:00104 params_(std::move(params)),
Shimi Zhang88ae9222019-07-19 16:54:16105 host_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
Maggie Chena6ece772020-04-27 17:19:06106 // Create a special GPU info collection service if the GPU process is used for
107 // info collection only.
108#if defined(OS_WIN)
109 if (params.info_collection_gpu_process) {
110 viz_main_->CreateInfoCollectionGpuService(
111 info_collection_gpu_service_remote_.BindNewPipeAndPassReceiver());
112 return;
113 }
114#endif
115
Mohsen Izadi0b9fbb62018-08-30 20:30:00116 DCHECK(delegate_);
Mohsen Izadi0b9fbb62018-08-30 20:30:00117
Julie Jeongeun Kim7b4a6aa12019-09-20 14:57:12118 mojo::PendingRemote<discardable_memory::mojom::DiscardableSharedMemoryManager>
119 discardable_manager_remote;
120 delegate_->BindDiscardableMemoryReceiver(
121 discardable_manager_remote.InitWithNewPipeAndPassReceiver());
Mohsen Izadi0b9fbb62018-08-30 20:30:00122
123 DCHECK(GetFontRenderParams().Get());
kylechar80dd2aa2019-07-22 15:31:39124 viz_main_->CreateGpuService(gpu_service_remote_.BindNewPipeAndPassReceiver(),
125 gpu_host_receiver_.BindNewPipeAndPassRemote(),
Julie Jeongeun Kim7b4a6aa12019-09-20 14:57:12126 std::move(discardable_manager_remote),
kylechar80dd2aa2019-07-22 15:31:39127 activity_flags_.CloneHandle(),
128 GetFontRenderParams().Get()->subpixel_rendering);
Mohsen Izadi63d85e72018-09-06 16:00:21129
130#if defined(USE_OZONE)
Maksim Sisov4f5918f2020-06-24 08:26:00131 if (features::IsUsingOzonePlatform())
132 InitOzone();
Mohsen Izadi63d85e72018-09-06 16:00:21133#endif // defined(USE_OZONE)
Mohsen Izadi0b9fbb62018-08-30 20:30:00134}
135
Mohsen Izadif9505d82018-10-06 01:34:03136GpuHostImpl::~GpuHostImpl() {
137 SendOutstandingReplies();
138}
Mohsen Izadi0b9fbb62018-08-30 20:30:00139
140// static
141void GpuHostImpl::InitFontRenderParams(const gfx::FontRenderParams& params) {
142 DCHECK(!GetFontRenderParams().Get());
143 GetFontRenderParams().Set(params);
144}
145
Mohsen Izadif9505d82018-10-06 01:34:03146// static
147void GpuHostImpl::ResetFontRenderParams() {
148 DCHECK(GetFontRenderParams().Get());
149 GetFontRenderParams().Reset();
150}
151
kylechar9b37f172019-09-19 22:55:27152void GpuHostImpl::SetProcessId(base::ProcessId pid) {
Mohsen Izadi0b9fbb62018-08-30 20:30:00153 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
154 DCHECK_EQ(base::kNullProcessId, pid_);
155 DCHECK_NE(base::kNullProcessId, pid);
156 pid_ = pid;
157}
158
159void GpuHostImpl::OnProcessCrashed() {
160 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
161
162 // If the GPU process crashed while compiling a shader, we may have invalid
163 // cached binaries. Completely clear the shader cache to force shader binaries
164 // to be re-created.
165 if (activity_flags_.IsFlagSet(
166 gpu::ActivityFlagsBase::FLAG_LOADING_PROGRAM_BINARY)) {
167 auto* shader_cache_factory = delegate_->GetShaderCacheFactory();
168 for (auto cache_key : client_id_to_shader_cache_) {
169 // This call will temporarily extend the lifetime of the cache (kept
170 // alive in the factory), and may drop loads of cached shader binaries if
171 // it takes a while to complete. As we are intentionally dropping all
172 // binaries, this behavior is fine.
173 shader_cache_factory->ClearByClientId(
174 cache_key.first, base::Time(), base::Time::Max(), base::DoNothing());
175 }
176 }
177}
178
Mohsen Izadibabed2b2018-08-31 01:37:39179void GpuHostImpl::AddConnectionErrorHandler(base::OnceClosure handler) {
180 connection_error_handlers_.push_back(std::move(handler));
181}
182
Mohsen Izadi0b9fbb62018-08-30 20:30:00183void GpuHostImpl::BlockLiveOffscreenContexts() {
184 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
185
186 for (auto iter = urls_with_live_offscreen_contexts_.begin();
187 iter != urls_with_live_offscreen_contexts_.end(); ++iter) {
Mohsen Izadi312c6922018-09-07 14:21:36188 delegate_->BlockDomainFrom3DAPIs(*iter, gpu::DomainGuilt::kUnknown);
Mohsen Izadi0b9fbb62018-08-30 20:30:00189 }
190}
191
192void GpuHostImpl::ConnectFrameSinkManager(
Mario Sanchez Prada745dd5e2019-10-16 14:14:30193 mojo::PendingReceiver<mojom::FrameSinkManager> receiver,
Alexander Alekseev81b01612020-07-10 22:56:29194 mojo::PendingRemote<mojom::FrameSinkManagerClient> client,
195 const DebugRendererSettings& debug_renderer_settings) {
Mohsen Izadi0b9fbb62018-08-30 20:30:00196 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
197 TRACE_EVENT0("gpu", "GpuHostImpl::ConnectFrameSinkManager");
198
199 mojom::FrameSinkManagerParamsPtr params =
200 mojom::FrameSinkManagerParams::New();
201 params->restart_id = params_.restart_id;
202 params->use_activation_deadline =
203 params_.deadline_to_synchronize_surfaces.has_value();
204 params->activation_deadline_in_frames =
205 params_.deadline_to_synchronize_surfaces.value_or(0u);
Mario Sanchez Prada745dd5e2019-10-16 14:14:30206 params->frame_sink_manager = std::move(receiver);
Mohsen Izadi0b9fbb62018-08-30 20:30:00207 params->frame_sink_manager_client = std::move(client);
Alexander Alekseev81b01612020-07-10 22:56:29208 params->debug_renderer_settings = debug_renderer_settings;
kylechar80dd2aa2019-07-22 15:31:39209 viz_main_->CreateFrameSinkManager(std::move(params));
Mohsen Izadi0b9fbb62018-08-30 20:30:00210}
211
Robert Seseka9b47c92019-08-30 01:22:54212#if BUILDFLAG(USE_VIZ_DEVTOOLS)
Sean Gilhulyda1ee4b2018-11-13 21:56:09213void GpuHostImpl::ConnectVizDevTools(mojom::VizDevToolsParamsPtr params) {
kylechar80dd2aa2019-07-22 15:31:39214 viz_main_->CreateVizDevTools(std::move(params));
Sean Gilhulyda1ee4b2018-11-13 21:56:09215}
216#endif
217
Mohsen Izadi0b9fbb62018-08-30 20:30:00218void GpuHostImpl::EstablishGpuChannel(int client_id,
219 uint64_t client_tracing_id,
220 bool is_gpu_host,
221 EstablishChannelCallback callback) {
222 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
223 TRACE_EVENT0("gpu", "GpuHostImpl::EstablishGpuChannel");
224
Bo Liu95570f32020-03-16 23:42:17225 shutdown_timeout_.Stop();
226
Mohsen Izadi0b9fbb62018-08-30 20:30:00227 // If GPU features are already blacklisted, no need to establish the channel.
228 if (!delegate_->GpuAccessAllowed()) {
229 DVLOG(1) << "GPU blacklisted, refusing to open a GPU channel.";
230 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
231 gpu::GpuFeatureInfo(),
232 EstablishChannelStatus::kGpuAccessDenied);
233 return;
234 }
235
236 if (gpu::IsReservedClientId(client_id)) {
237 // The display-compositor/GrShaderCache in the gpu process uses these
238 // special client ids.
239 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
240 gpu::GpuFeatureInfo(),
241 EstablishChannelStatus::kGpuAccessDenied);
242 return;
243 }
244
245 bool cache_shaders_on_disk =
246 delegate_->GetShaderCacheFactory()->Get(client_id) != nullptr;
247
248 channel_requests_.push(std::move(callback));
Shimi Zhang88ae9222019-07-19 16:54:16249 gpu_service_remote_->EstablishGpuChannel(
Mohsen Izadi0b9fbb62018-08-30 20:30:00250 client_id, client_tracing_id, is_gpu_host, cache_shaders_on_disk,
251 base::BindOnce(&GpuHostImpl::OnChannelEstablished,
252 weak_ptr_factory_.GetWeakPtr(), client_id));
253
Jonathan Backer06c419e12019-01-22 14:37:14254 if (!params_.disable_gpu_shader_disk_cache)
Mohsen Izadi0b9fbb62018-08-30 20:30:00255 CreateChannelCache(client_id);
Mohsen Izadi0b9fbb62018-08-30 20:30:00256}
257
258void GpuHostImpl::SendOutstandingReplies() {
259 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
260
Mohsen Izadibabed2b2018-08-31 01:37:39261 for (auto& handler : connection_error_handlers_)
262 std::move(handler).Run();
263 connection_error_handlers_.clear();
264
Mohsen Izadi0b9fbb62018-08-30 20:30:00265 // Send empty channel handles for all EstablishChannel requests.
266 while (!channel_requests_.empty()) {
267 auto callback = std::move(channel_requests_.front());
268 channel_requests_.pop();
269 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
270 gpu::GpuFeatureInfo(),
271 EstablishChannelStatus::kGpuHostInvalid);
272 }
273}
274
Mohsen Izadi63d85e72018-09-06 16:00:21275void GpuHostImpl::BindInterface(const std::string& interface_name,
276 mojo::ScopedMessagePipeHandle interface_pipe) {
277 delegate_->BindInterface(interface_name, std::move(interface_pipe));
278}
279
Ken Rockotb2928f32019-03-12 04:43:03280void GpuHostImpl::RunService(
281 const std::string& service_name,
282 mojo::PendingReceiver<service_manager::mojom::Service> receiver) {
283 delegate_->RunService(service_name, std::move(receiver));
284}
285
Mohsen Izadi0b9fbb62018-08-30 20:30:00286mojom::GpuService* GpuHostImpl::gpu_service() {
287 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Shimi Zhang88ae9222019-07-19 16:54:16288 DCHECK(gpu_service_remote_.is_bound());
289 return gpu_service_remote_.get();
Mohsen Izadi0b9fbb62018-08-30 20:30:00290}
291
Maggie Chena6ece772020-04-27 17:19:06292#if defined(OS_WIN)
293mojom::InfoCollectionGpuService* GpuHostImpl::info_collection_gpu_service() {
294 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
295 DCHECK(info_collection_gpu_service_remote_.is_bound());
296 return info_collection_gpu_service_remote_.get();
297}
298#endif
299
Mohsen Izadi63d85e72018-09-06 16:00:21300#if defined(USE_OZONE)
Mohsen Izadia378a8f42019-08-02 02:34:19301
Mohsen Izadi63d85e72018-09-06 16:00:21302void GpuHostImpl::InitOzone() {
Maksim Sisov4f5918f2020-06-24 08:26:00303 DCHECK(features::IsUsingOzonePlatform());
Mohsen Izadi63d85e72018-09-06 16:00:21304 // Ozone needs to send the primary DRM device to GPU service as early as
305 // possible to ensure the latter always has a valid device.
306 // https://crbug.com/608839
Maksim Sisov2e064342018-10-03 10:35:06307 //
308 // The Ozone/Wayland requires mojo communication to be established to be
309 // functional with a separate gpu process. Thus, using the PlatformProperties,
310 // check if there is such a requirement.
Kramer Gec78fde4e2020-04-18 18:58:06311 auto interface_binder = base::BindRepeating(&GpuHostImpl::BindInterface,
312 weak_ptr_factory_.GetWeakPtr());
313 auto terminate_callback = base::BindOnce(&GpuHostImpl::TerminateGpuProcess,
314 weak_ptr_factory_.GetWeakPtr());
Mohsen Izadi63d85e72018-09-06 16:00:21315
Kramer Gec78fde4e2020-04-18 18:58:06316 ui::OzonePlatform::GetInstance()
317 ->GetGpuPlatformSupportHost()
318 ->OnGpuServiceLaunched(params_.restart_id,
319 params_.main_thread_task_runner,
320 host_thread_task_runner_, interface_binder,
321 std::move(terminate_callback));
Mohsen Izadi63d85e72018-09-06 16:00:21322}
323
324void GpuHostImpl::TerminateGpuProcess(const std::string& message) {
325 delegate_->TerminateGpuProcess(message);
326}
327
328#endif // defined(USE_OZONE)
329
Mohsen Izadi0b9fbb62018-08-30 20:30:00330std::string GpuHostImpl::GetShaderPrefixKey() {
331 if (shader_prefix_key_.empty()) {
332 const gpu::GPUInfo& info = delegate_->GetGPUInfo();
333 const gpu::GPUInfo::GPUDevice& active_gpu = info.active_gpu();
334
335 shader_prefix_key_ = params_.product + "-" + info.gl_vendor + "-" +
336 info.gl_renderer + "-" + active_gpu.driver_version +
337 "-" + active_gpu.driver_vendor;
338
339#if defined(OS_ANDROID)
340 std::string build_fp =
341 base::android::BuildInfo::GetInstance()->android_build_fp();
Mohsen Izadi0b9fbb62018-08-30 20:30:00342 shader_prefix_key_ += "-" + build_fp;
343#endif
344 }
345
346 return shader_prefix_key_;
347}
348
349void GpuHostImpl::LoadedShader(int32_t client_id,
350 const std::string& key,
351 const std::string& data) {
352 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
353
354 std::string prefix = GetShaderPrefixKey();
355 bool prefix_ok = !key.compare(0, prefix.length(), prefix);
356 UMA_HISTOGRAM_BOOLEAN("GPU.ShaderLoadPrefixOK", prefix_ok);
357 if (prefix_ok) {
358 // Remove the prefix from the key before load.
359 std::string key_no_prefix = key.substr(prefix.length() + 1);
Shimi Zhang88ae9222019-07-19 16:54:16360 gpu_service_remote_->LoadedShader(client_id, key_no_prefix, data);
Mohsen Izadi0b9fbb62018-08-30 20:30:00361 }
362}
363
364void GpuHostImpl::CreateChannelCache(int32_t client_id) {
365 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
366 TRACE_EVENT0("gpu", "GpuHostImpl::CreateChannelCache");
367
368 scoped_refptr<gpu::ShaderDiskCache> cache =
369 delegate_->GetShaderCacheFactory()->Get(client_id);
370 if (!cache)
371 return;
372
373 cache->set_shader_loaded_callback(base::BindRepeating(
374 &GpuHostImpl::LoadedShader, weak_ptr_factory_.GetWeakPtr(), client_id));
375
376 client_id_to_shader_cache_[client_id] = cache;
377}
378
379void GpuHostImpl::OnChannelEstablished(
380 int client_id,
381 mojo::ScopedMessagePipeHandle channel_handle) {
382 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
383 TRACE_EVENT0("gpu", "GpuHostImpl::OnChannelEstablished");
384
385 DCHECK(!channel_requests_.empty());
386 auto callback = std::move(channel_requests_.front());
387 channel_requests_.pop();
388
389 // Currently if any of the GPU features are blacklisted, we don't establish a
390 // GPU channel.
391 if (channel_handle.is_valid() && !delegate_->GpuAccessAllowed()) {
Shimi Zhang88ae9222019-07-19 16:54:16392 gpu_service_remote_->CloseChannel(client_id);
Mohsen Izadi0b9fbb62018-08-30 20:30:00393 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
394 gpu::GpuFeatureInfo(),
395 EstablishChannelStatus::kGpuAccessDenied);
396 RecordLogMessage(logging::LOG_WARNING, "WARNING",
397 "Hardware acceleration is unavailable.");
398 return;
399 }
400
401 std::move(callback).Run(std::move(channel_handle), delegate_->GetGPUInfo(),
402 delegate_->GetGpuFeatureInfo(),
403 EstablishChannelStatus::kSuccess);
404}
405
406void GpuHostImpl::DidInitialize(
407 const gpu::GPUInfo& gpu_info,
408 const gpu::GpuFeatureInfo& gpu_feature_info,
409 const base::Optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu,
410 const base::Optional<gpu::GpuFeatureInfo>&
Jonah Ryan-Davisa70577c2019-06-26 18:54:31411 gpu_feature_info_for_hardware_gpu,
412 const gpu::GpuExtraInfo& gpu_extra_info) {
Mohsen Izadi0b9fbb62018-08-30 20:30:00413 UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", true);
Mohsen Izadi0b9fbb62018-08-30 20:30:00414
415 // Set GPU driver bug workaround flags that are checked on the browser side.
416 wake_up_gpu_before_drawing_ =
417 gpu_feature_info.IsWorkaroundEnabled(gpu::WAKE_UP_GPU_BEFORE_DRAWING);
418 dont_disable_webgl_when_compositor_context_lost_ =
419 gpu_feature_info.IsWorkaroundEnabled(
420 gpu::DONT_DISABLE_WEBGL_WHEN_COMPOSITOR_CONTEXT_LOST);
421
Mohsen Izadif9505d82018-10-06 01:34:03422 delegate_->DidInitialize(gpu_info, gpu_feature_info,
Mohsen Izadi0b9fbb62018-08-30 20:30:00423 gpu_info_for_hardware_gpu,
Jonah Ryan-Davisa70577c2019-06-26 18:54:31424 gpu_feature_info_for_hardware_gpu, gpu_extra_info);
Jonathan Backer06c419e12019-01-22 14:37:14425
426 if (!params_.disable_gpu_shader_disk_cache) {
kylechar90f620c2020-08-18 17:08:41427 CreateChannelCache(gpu::kDisplayCompositorClientId);
Jonathan Backer06c419e12019-01-22 14:37:14428
Peng Huang70021682019-09-18 19:42:28429 bool use_gr_shader_cache = base::FeatureList::IsEnabled(
430 features::kDefaultEnableOopRasterization) ||
431 features::IsUsingSkiaRenderer();
Jonathan Backer06c419e12019-01-22 14:37:14432 if (use_gr_shader_cache)
433 CreateChannelCache(gpu::kGrShaderCacheClientId);
434 }
Mohsen Izadi0b9fbb62018-08-30 20:30:00435}
436
437void GpuHostImpl::DidFailInitialize() {
438 UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", false);
439 delegate_->DidFailInitialize();
440}
441
442void GpuHostImpl::DidCreateContextSuccessfully() {
443 delegate_->DidCreateContextSuccessfully();
444}
445
446void GpuHostImpl::DidCreateOffscreenContext(const GURL& url) {
447 urls_with_live_offscreen_contexts_.insert(url);
448}
449
450void GpuHostImpl::DidDestroyOffscreenContext(const GURL& url) {
451 // We only want to remove *one* of the entries in the multiset for this
452 // particular URL, so can't use the erase method taking a key.
453 auto candidate = urls_with_live_offscreen_contexts_.find(url);
454 if (candidate != urls_with_live_offscreen_contexts_.end())
455 urls_with_live_offscreen_contexts_.erase(candidate);
456}
457
458void GpuHostImpl::DidDestroyChannel(int32_t client_id) {
459 TRACE_EVENT0("gpu", "GpuHostImpl::DidDestroyChannel");
460 client_id_to_shader_cache_.erase(client_id);
461}
462
Bo Liu95570f32020-03-16 23:42:17463void GpuHostImpl::DidDestroyAllChannels() {
464 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
465 if (!channel_requests_.empty())
466 return;
467 constexpr base::TimeDelta kShutDownTimeout = base::TimeDelta::FromSeconds(10);
468 shutdown_timeout_.Start(FROM_HERE, kShutDownTimeout,
469 base::BindOnce(&GpuHostImpl::MaybeShutdownGpuProcess,
470 base::Unretained(this)));
471}
472
473void GpuHostImpl::MaybeShutdownGpuProcess() {
474 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
475 DCHECK(channel_requests_.empty());
476 delegate_->MaybeShutdownGpuProcess();
477}
478
Mohsen Izadi0b9fbb62018-08-30 20:30:00479void GpuHostImpl::DidLoseContext(bool offscreen,
480 gpu::error::ContextLostReason reason,
481 const GURL& active_url) {
482 // TODO(kbr): would be nice to see the "offscreen" flag too.
483 TRACE_EVENT2("gpu", "GpuHostImpl::DidLoseContext", "reason", reason, "url",
484 active_url.possibly_invalid_spec());
485
Patrick Todf5911c2020-05-12 19:31:42486 if (active_url.is_empty()) {
Mohsen Izadi0b9fbb62018-08-30 20:30:00487 return;
488 }
489
Mohsen Izadi312c6922018-09-07 14:21:36490 gpu::DomainGuilt guilt = gpu::DomainGuilt::kUnknown;
Mohsen Izadi0b9fbb62018-08-30 20:30:00491 switch (reason) {
492 case gpu::error::kGuilty:
Mohsen Izadi312c6922018-09-07 14:21:36493 guilt = gpu::DomainGuilt::kKnown;
Mohsen Izadi0b9fbb62018-08-30 20:30:00494 break;
495 // Treat most other error codes as though they had unknown provenance.
496 // In practice this doesn't affect the user experience. A lost context
497 // of either known or unknown guilt still causes user-level 3D APIs
498 // (e.g. WebGL) to be blocked on that domain until the user manually
499 // reenables them.
500 case gpu::error::kUnknown:
501 case gpu::error::kOutOfMemory:
502 case gpu::error::kMakeCurrentFailed:
503 case gpu::error::kGpuChannelLost:
504 case gpu::error::kInvalidGpuMessage:
505 break;
506 case gpu::error::kInnocent:
507 return;
508 }
509
510 delegate_->BlockDomainFrom3DAPIs(active_url, guilt);
511}
512
513void GpuHostImpl::DisableGpuCompositing() {
514 delegate_->DisableGpuCompositing();
515}
516
Mohsen Izadi50c28052018-09-07 00:32:14517#if defined(OS_WIN)
Maggie Chen8f177172020-02-11 00:02:28518void GpuHostImpl::DidUpdateOverlayInfo(const gpu::OverlayInfo& overlay_info) {
519 delegate_->DidUpdateOverlayInfo(overlay_info);
520}
521
Maggie Chen05364bf32020-06-03 08:34:06522void GpuHostImpl::DidUpdateHDRStatus(bool hdr_enabled) {
523 delegate_->DidUpdateHDRStatus(hdr_enabled);
524}
525
Mohsen Izadi0b9fbb62018-08-30 20:30:00526void GpuHostImpl::SetChildSurface(gpu::SurfaceHandle parent,
527 gpu::SurfaceHandle child) {
kylechar89341da82018-09-10 15:26:27528 if (pid_ != base::kNullProcessId) {
529 gfx::RenderingWindowManager::GetInstance()->RegisterChild(
530 parent, child, /*expected_child_process_id=*/pid_);
Mohsen Izadi0b9fbb62018-08-30 20:30:00531 }
Mohsen Izadi0b9fbb62018-08-30 20:30:00532}
Mohsen Izadi50c28052018-09-07 00:32:14533#endif // defined(OS_WIN)
Mohsen Izadi0b9fbb62018-08-30 20:30:00534
535void GpuHostImpl::StoreShaderToDisk(int32_t client_id,
536 const std::string& key,
537 const std::string& shader) {
538 TRACE_EVENT0("gpu", "GpuHostImpl::StoreShaderToDisk");
539 auto iter = client_id_to_shader_cache_.find(client_id);
540 // If the cache doesn't exist then this is an off the record profile.
541 if (iter == client_id_to_shader_cache_.end())
542 return;
543 std::string prefix = GetShaderPrefixKey();
544 iter->second->Cache(prefix + ":" + key, shader);
545}
546
547void GpuHostImpl::RecordLogMessage(int32_t severity,
548 const std::string& header,
549 const std::string& message) {
550 delegate_->RecordLogMessage(severity, header, message);
551}
552
553} // namespace viz