blob: 851169e1e5df6a3494dbb3863ca7a34078021bdb [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"
danakjdb9ae7942020-11-11 16:01:3510#include "base/callback_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"
Mohsen Izadi0b9fbb62018-08-30 20:30:0020#include "gpu/config/gpu_feature_info.h"
21#include "gpu/config/gpu_finch_features.h"
22#include "gpu/config/gpu_info.h"
23#include "gpu/ipc/common/gpu_client_ids.h"
24#include "gpu/ipc/host/shader_disk_cache.h"
Mohsen Izadi63d85e72018-09-06 16:00:2125#include "ui/base/ui_base_features.h"
Mohsen Izadi0b9fbb62018-08-30 20:30:0026#include "ui/gfx/font_render_params.h"
27
28#if defined(OS_ANDROID)
29#include "base/android/build_info.h"
30#endif
31
32#if defined(OS_WIN)
33#include "ui/gfx/win/rendering_window_manager.h"
34#endif
35
Maksim Sisov4f5918f2020-06-24 08:26:0036#if defined(USE_OZONE)
Peng Huang2d5cf682020-07-31 14:07:4737#include "ui/ozone/public/gpu_platform_support_host.h"
38#include "ui/ozone/public/ozone_platform.h"
Maksim Sisov4f5918f2020-06-24 08:26:0039#endif
40
Mohsen Izadi0b9fbb62018-08-30 20:30:0041namespace viz {
42namespace {
43
44// A wrapper around gfx::FontRenderParams that checks it is set and accessed on
45// the same thread.
46class FontRenderParams {
47 public:
48 void Set(const gfx::FontRenderParams& params);
Mohsen Izadif9505d82018-10-06 01:34:0349 void Reset();
Mohsen Izadi0b9fbb62018-08-30 20:30:0050 const base::Optional<gfx::FontRenderParams>& Get();
51
52 private:
53 friend class base::NoDestructor<FontRenderParams>;
54
55 FontRenderParams();
56 ~FontRenderParams();
57
58 THREAD_CHECKER(thread_checker_);
59 base::Optional<gfx::FontRenderParams> params_;
60
61 DISALLOW_COPY_AND_ASSIGN(FontRenderParams);
62};
63
64void FontRenderParams::Set(const gfx::FontRenderParams& params) {
65 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
66 params_ = params;
67}
68
Mohsen Izadif9505d82018-10-06 01:34:0369void FontRenderParams::Reset() {
70 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
71 params_ = base::nullopt;
72}
73
Mohsen Izadi0b9fbb62018-08-30 20:30:0074const base::Optional<gfx::FontRenderParams>& FontRenderParams::Get() {
75 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
76 return params_;
77}
78
79FontRenderParams::FontRenderParams() = default;
80
81FontRenderParams::~FontRenderParams() {
82 NOTREACHED();
83}
84
85FontRenderParams& GetFontRenderParams() {
86 static base::NoDestructor<FontRenderParams> instance;
87 return *instance;
88}
89
90} // namespace
91
92GpuHostImpl::InitParams::InitParams() = default;
93
94GpuHostImpl::InitParams::InitParams(InitParams&&) = default;
95
96GpuHostImpl::InitParams::~InitParams() = default;
97
98GpuHostImpl::GpuHostImpl(Delegate* delegate,
kylechar80dd2aa2019-07-22 15:31:3999 mojo::PendingAssociatedRemote<mojom::VizMain> viz_main,
Mohsen Izadi0b9fbb62018-08-30 20:30:00100 InitParams params)
101 : delegate_(delegate),
kylechar80dd2aa2019-07-22 15:31:39102 viz_main_(std::move(viz_main)),
Mohsen Izadi0b9fbb62018-08-30 20:30:00103 params_(std::move(params)),
Shimi Zhang88ae9222019-07-19 16:54:16104 host_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
Maggie Chena6ece772020-04-27 17:19:06105 // Create a special GPU info collection service if the GPU process is used for
106 // info collection only.
107#if defined(OS_WIN)
108 if (params.info_collection_gpu_process) {
109 viz_main_->CreateInfoCollectionGpuService(
110 info_collection_gpu_service_remote_.BindNewPipeAndPassReceiver());
111 return;
112 }
113#endif
114
Mohsen Izadi0b9fbb62018-08-30 20:30:00115 DCHECK(delegate_);
Mohsen Izadi0b9fbb62018-08-30 20:30:00116
Julie Jeongeun Kim7b4a6aa12019-09-20 14:57:12117 mojo::PendingRemote<discardable_memory::mojom::DiscardableSharedMemoryManager>
118 discardable_manager_remote;
119 delegate_->BindDiscardableMemoryReceiver(
120 discardable_manager_remote.InitWithNewPipeAndPassReceiver());
Mohsen Izadi0b9fbb62018-08-30 20:30:00121
122 DCHECK(GetFontRenderParams().Get());
kylechar80dd2aa2019-07-22 15:31:39123 viz_main_->CreateGpuService(gpu_service_remote_.BindNewPipeAndPassReceiver(),
124 gpu_host_receiver_.BindNewPipeAndPassRemote(),
Julie Jeongeun Kim7b4a6aa12019-09-20 14:57:12125 std::move(discardable_manager_remote),
kylechar80dd2aa2019-07-22 15:31:39126 activity_flags_.CloneHandle(),
127 GetFontRenderParams().Get()->subpixel_rendering);
Mohsen Izadi63d85e72018-09-06 16:00:21128
129#if defined(USE_OZONE)
Maksim Sisov4f5918f2020-06-24 08:26:00130 if (features::IsUsingOzonePlatform())
131 InitOzone();
Mohsen Izadi63d85e72018-09-06 16:00:21132#endif // defined(USE_OZONE)
Mohsen Izadi0b9fbb62018-08-30 20:30:00133}
134
Mohsen Izadif9505d82018-10-06 01:34:03135GpuHostImpl::~GpuHostImpl() {
136 SendOutstandingReplies();
137}
Mohsen Izadi0b9fbb62018-08-30 20:30:00138
139// static
140void GpuHostImpl::InitFontRenderParams(const gfx::FontRenderParams& params) {
141 DCHECK(!GetFontRenderParams().Get());
142 GetFontRenderParams().Set(params);
143}
144
Mohsen Izadif9505d82018-10-06 01:34:03145// static
146void GpuHostImpl::ResetFontRenderParams() {
147 DCHECK(GetFontRenderParams().Get());
148 GetFontRenderParams().Reset();
149}
150
kylechar9b37f172019-09-19 22:55:27151void GpuHostImpl::SetProcessId(base::ProcessId pid) {
Mohsen Izadi0b9fbb62018-08-30 20:30:00152 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
153 DCHECK_EQ(base::kNullProcessId, pid_);
154 DCHECK_NE(base::kNullProcessId, pid);
155 pid_ = pid;
156}
157
158void GpuHostImpl::OnProcessCrashed() {
159 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
160
161 // If the GPU process crashed while compiling a shader, we may have invalid
162 // cached binaries. Completely clear the shader cache to force shader binaries
163 // to be re-created.
164 if (activity_flags_.IsFlagSet(
165 gpu::ActivityFlagsBase::FLAG_LOADING_PROGRAM_BINARY)) {
166 auto* shader_cache_factory = delegate_->GetShaderCacheFactory();
167 for (auto cache_key : client_id_to_shader_cache_) {
168 // This call will temporarily extend the lifetime of the cache (kept
169 // alive in the factory), and may drop loads of cached shader binaries if
170 // it takes a while to complete. As we are intentionally dropping all
171 // binaries, this behavior is fine.
172 shader_cache_factory->ClearByClientId(
173 cache_key.first, base::Time(), base::Time::Max(), base::DoNothing());
174 }
175 }
176}
177
Mohsen Izadibabed2b2018-08-31 01:37:39178void GpuHostImpl::AddConnectionErrorHandler(base::OnceClosure handler) {
179 connection_error_handlers_.push_back(std::move(handler));
180}
181
Mohsen Izadi0b9fbb62018-08-30 20:30:00182void GpuHostImpl::BlockLiveOffscreenContexts() {
183 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
184
185 for (auto iter = urls_with_live_offscreen_contexts_.begin();
186 iter != urls_with_live_offscreen_contexts_.end(); ++iter) {
Mohsen Izadi312c6922018-09-07 14:21:36187 delegate_->BlockDomainFrom3DAPIs(*iter, gpu::DomainGuilt::kUnknown);
Mohsen Izadi0b9fbb62018-08-30 20:30:00188 }
189}
190
191void GpuHostImpl::ConnectFrameSinkManager(
Mario Sanchez Prada745dd5e2019-10-16 14:14:30192 mojo::PendingReceiver<mojom::FrameSinkManager> receiver,
Alexander Alekseev81b01612020-07-10 22:56:29193 mojo::PendingRemote<mojom::FrameSinkManagerClient> client,
194 const DebugRendererSettings& debug_renderer_settings) {
Mohsen Izadi0b9fbb62018-08-30 20:30:00195 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
196 TRACE_EVENT0("gpu", "GpuHostImpl::ConnectFrameSinkManager");
197
198 mojom::FrameSinkManagerParamsPtr params =
199 mojom::FrameSinkManagerParams::New();
200 params->restart_id = params_.restart_id;
201 params->use_activation_deadline =
202 params_.deadline_to_synchronize_surfaces.has_value();
203 params->activation_deadline_in_frames =
204 params_.deadline_to_synchronize_surfaces.value_or(0u);
Mario Sanchez Prada745dd5e2019-10-16 14:14:30205 params->frame_sink_manager = std::move(receiver);
Mohsen Izadi0b9fbb62018-08-30 20:30:00206 params->frame_sink_manager_client = std::move(client);
Alexander Alekseev81b01612020-07-10 22:56:29207 params->debug_renderer_settings = debug_renderer_settings;
kylechar80dd2aa2019-07-22 15:31:39208 viz_main_->CreateFrameSinkManager(std::move(params));
Mohsen Izadi0b9fbb62018-08-30 20:30:00209}
210
Robert Seseka9b47c92019-08-30 01:22:54211#if BUILDFLAG(USE_VIZ_DEVTOOLS)
Sean Gilhulyda1ee4b2018-11-13 21:56:09212void GpuHostImpl::ConnectVizDevTools(mojom::VizDevToolsParamsPtr params) {
kylechar80dd2aa2019-07-22 15:31:39213 viz_main_->CreateVizDevTools(std::move(params));
Sean Gilhulyda1ee4b2018-11-13 21:56:09214}
215#endif
216
Mohsen Izadi0b9fbb62018-08-30 20:30:00217void GpuHostImpl::EstablishGpuChannel(int client_id,
218 uint64_t client_tracing_id,
219 bool is_gpu_host,
220 EstablishChannelCallback callback) {
221 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
222 TRACE_EVENT0("gpu", "GpuHostImpl::EstablishGpuChannel");
223
Bo Liu95570f32020-03-16 23:42:17224 shutdown_timeout_.Stop();
225
Sean Gilhulyd2ef4022020-08-20 18:18:56226 // If GPU features are already blocklisted, no need to establish the channel.
Mohsen Izadi0b9fbb62018-08-30 20:30:00227 if (!delegate_->GpuAccessAllowed()) {
Sean Gilhulyd2ef4022020-08-20 18:18:56228 DVLOG(1) << "GPU access blocked, refusing to open a GPU channel.";
Mohsen Izadi0b9fbb62018-08-30 20:30:00229 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
230 gpu::GpuFeatureInfo(),
231 EstablishChannelStatus::kGpuAccessDenied);
232 return;
233 }
234
235 if (gpu::IsReservedClientId(client_id)) {
236 // The display-compositor/GrShaderCache in the gpu process uses these
237 // special client ids.
238 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
239 gpu::GpuFeatureInfo(),
240 EstablishChannelStatus::kGpuAccessDenied);
241 return;
242 }
243
244 bool cache_shaders_on_disk =
245 delegate_->GetShaderCacheFactory()->Get(client_id) != nullptr;
246
247 channel_requests_.push(std::move(callback));
Shimi Zhang88ae9222019-07-19 16:54:16248 gpu_service_remote_->EstablishGpuChannel(
Mohsen Izadi0b9fbb62018-08-30 20:30:00249 client_id, client_tracing_id, is_gpu_host, cache_shaders_on_disk,
250 base::BindOnce(&GpuHostImpl::OnChannelEstablished,
251 weak_ptr_factory_.GetWeakPtr(), client_id));
252
Jonathan Backer06c419e12019-01-22 14:37:14253 if (!params_.disable_gpu_shader_disk_cache)
Mohsen Izadi0b9fbb62018-08-30 20:30:00254 CreateChannelCache(client_id);
Mohsen Izadi0b9fbb62018-08-30 20:30:00255}
256
257void GpuHostImpl::SendOutstandingReplies() {
258 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
259
Mohsen Izadibabed2b2018-08-31 01:37:39260 for (auto& handler : connection_error_handlers_)
261 std::move(handler).Run();
262 connection_error_handlers_.clear();
263
Mohsen Izadi0b9fbb62018-08-30 20:30:00264 // Send empty channel handles for all EstablishChannel requests.
265 while (!channel_requests_.empty()) {
266 auto callback = std::move(channel_requests_.front());
267 channel_requests_.pop();
268 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
269 gpu::GpuFeatureInfo(),
270 EstablishChannelStatus::kGpuHostInvalid);
271 }
272}
273
Mohsen Izadi63d85e72018-09-06 16:00:21274void GpuHostImpl::BindInterface(const std::string& interface_name,
275 mojo::ScopedMessagePipeHandle interface_pipe) {
276 delegate_->BindInterface(interface_name, std::move(interface_pipe));
277}
278
Mohsen Izadi0b9fbb62018-08-30 20:30:00279mojom::GpuService* GpuHostImpl::gpu_service() {
280 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Shimi Zhang88ae9222019-07-19 16:54:16281 DCHECK(gpu_service_remote_.is_bound());
282 return gpu_service_remote_.get();
Mohsen Izadi0b9fbb62018-08-30 20:30:00283}
284
Maggie Chena6ece772020-04-27 17:19:06285#if defined(OS_WIN)
286mojom::InfoCollectionGpuService* GpuHostImpl::info_collection_gpu_service() {
287 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
288 DCHECK(info_collection_gpu_service_remote_.is_bound());
289 return info_collection_gpu_service_remote_.get();
290}
291#endif
292
Mohsen Izadi63d85e72018-09-06 16:00:21293#if defined(USE_OZONE)
Mohsen Izadia378a8f42019-08-02 02:34:19294
Mohsen Izadi63d85e72018-09-06 16:00:21295void GpuHostImpl::InitOzone() {
Maksim Sisov4f5918f2020-06-24 08:26:00296 DCHECK(features::IsUsingOzonePlatform());
Mohsen Izadi63d85e72018-09-06 16:00:21297 // Ozone needs to send the primary DRM device to GPU service as early as
298 // possible to ensure the latter always has a valid device.
299 // https://crbug.com/608839
Maksim Sisov2e064342018-10-03 10:35:06300 //
301 // The Ozone/Wayland requires mojo communication to be established to be
302 // functional with a separate gpu process. Thus, using the PlatformProperties,
303 // check if there is such a requirement.
Kramer Gec78fde4e2020-04-18 18:58:06304 auto interface_binder = base::BindRepeating(&GpuHostImpl::BindInterface,
305 weak_ptr_factory_.GetWeakPtr());
306 auto terminate_callback = base::BindOnce(&GpuHostImpl::TerminateGpuProcess,
307 weak_ptr_factory_.GetWeakPtr());
Mohsen Izadi63d85e72018-09-06 16:00:21308
Kramer Gec78fde4e2020-04-18 18:58:06309 ui::OzonePlatform::GetInstance()
310 ->GetGpuPlatformSupportHost()
311 ->OnGpuServiceLaunched(params_.restart_id,
312 params_.main_thread_task_runner,
313 host_thread_task_runner_, interface_binder,
314 std::move(terminate_callback));
Mohsen Izadi63d85e72018-09-06 16:00:21315}
316
317void GpuHostImpl::TerminateGpuProcess(const std::string& message) {
318 delegate_->TerminateGpuProcess(message);
319}
320
321#endif // defined(USE_OZONE)
322
Mohsen Izadi0b9fbb62018-08-30 20:30:00323std::string GpuHostImpl::GetShaderPrefixKey() {
324 if (shader_prefix_key_.empty()) {
325 const gpu::GPUInfo& info = delegate_->GetGPUInfo();
326 const gpu::GPUInfo::GPUDevice& active_gpu = info.active_gpu();
327
328 shader_prefix_key_ = params_.product + "-" + info.gl_vendor + "-" +
329 info.gl_renderer + "-" + active_gpu.driver_version +
330 "-" + active_gpu.driver_vendor;
331
332#if defined(OS_ANDROID)
333 std::string build_fp =
334 base::android::BuildInfo::GetInstance()->android_build_fp();
Mohsen Izadi0b9fbb62018-08-30 20:30:00335 shader_prefix_key_ += "-" + build_fp;
336#endif
337 }
338
339 return shader_prefix_key_;
340}
341
342void GpuHostImpl::LoadedShader(int32_t client_id,
343 const std::string& key,
344 const std::string& data) {
345 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
346
347 std::string prefix = GetShaderPrefixKey();
348 bool prefix_ok = !key.compare(0, prefix.length(), prefix);
349 UMA_HISTOGRAM_BOOLEAN("GPU.ShaderLoadPrefixOK", prefix_ok);
350 if (prefix_ok) {
351 // Remove the prefix from the key before load.
352 std::string key_no_prefix = key.substr(prefix.length() + 1);
Shimi Zhang88ae9222019-07-19 16:54:16353 gpu_service_remote_->LoadedShader(client_id, key_no_prefix, data);
Mohsen Izadi0b9fbb62018-08-30 20:30:00354 }
355}
356
357void GpuHostImpl::CreateChannelCache(int32_t client_id) {
358 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
359 TRACE_EVENT0("gpu", "GpuHostImpl::CreateChannelCache");
360
361 scoped_refptr<gpu::ShaderDiskCache> cache =
362 delegate_->GetShaderCacheFactory()->Get(client_id);
363 if (!cache)
364 return;
365
366 cache->set_shader_loaded_callback(base::BindRepeating(
367 &GpuHostImpl::LoadedShader, weak_ptr_factory_.GetWeakPtr(), client_id));
368
369 client_id_to_shader_cache_[client_id] = cache;
370}
371
372void GpuHostImpl::OnChannelEstablished(
373 int client_id,
374 mojo::ScopedMessagePipeHandle channel_handle) {
375 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
376 TRACE_EVENT0("gpu", "GpuHostImpl::OnChannelEstablished");
377
378 DCHECK(!channel_requests_.empty());
379 auto callback = std::move(channel_requests_.front());
380 channel_requests_.pop();
381
Sean Gilhulyd2ef4022020-08-20 18:18:56382 // Currently if any of the GPU features are blocklisted, we don't establish a
Mohsen Izadi0b9fbb62018-08-30 20:30:00383 // GPU channel.
384 if (channel_handle.is_valid() && !delegate_->GpuAccessAllowed()) {
Shimi Zhang88ae9222019-07-19 16:54:16385 gpu_service_remote_->CloseChannel(client_id);
Mohsen Izadi0b9fbb62018-08-30 20:30:00386 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
387 gpu::GpuFeatureInfo(),
388 EstablishChannelStatus::kGpuAccessDenied);
389 RecordLogMessage(logging::LOG_WARNING, "WARNING",
390 "Hardware acceleration is unavailable.");
391 return;
392 }
393
394 std::move(callback).Run(std::move(channel_handle), delegate_->GetGPUInfo(),
395 delegate_->GetGpuFeatureInfo(),
396 EstablishChannelStatus::kSuccess);
397}
398
399void GpuHostImpl::DidInitialize(
400 const gpu::GPUInfo& gpu_info,
401 const gpu::GpuFeatureInfo& gpu_feature_info,
402 const base::Optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu,
403 const base::Optional<gpu::GpuFeatureInfo>&
Jonah Ryan-Davisa70577c2019-06-26 18:54:31404 gpu_feature_info_for_hardware_gpu,
Alexander Dunaeve6e09c12020-10-23 16:43:42405 const gfx::GpuExtraInfo& gpu_extra_info) {
Mohsen Izadi0b9fbb62018-08-30 20:30:00406 UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", true);
Mohsen Izadi0b9fbb62018-08-30 20:30:00407
408 // Set GPU driver bug workaround flags that are checked on the browser side.
409 wake_up_gpu_before_drawing_ =
410 gpu_feature_info.IsWorkaroundEnabled(gpu::WAKE_UP_GPU_BEFORE_DRAWING);
411 dont_disable_webgl_when_compositor_context_lost_ =
412 gpu_feature_info.IsWorkaroundEnabled(
413 gpu::DONT_DISABLE_WEBGL_WHEN_COMPOSITOR_CONTEXT_LOST);
414
Mohsen Izadif9505d82018-10-06 01:34:03415 delegate_->DidInitialize(gpu_info, gpu_feature_info,
Mohsen Izadi0b9fbb62018-08-30 20:30:00416 gpu_info_for_hardware_gpu,
Jonah Ryan-Davisa70577c2019-06-26 18:54:31417 gpu_feature_info_for_hardware_gpu, gpu_extra_info);
Jonathan Backer06c419e12019-01-22 14:37:14418
419 if (!params_.disable_gpu_shader_disk_cache) {
kylechar90f620c2020-08-18 17:08:41420 CreateChannelCache(gpu::kDisplayCompositorClientId);
Jonathan Backer06c419e12019-01-22 14:37:14421
Peng Huang70021682019-09-18 19:42:28422 bool use_gr_shader_cache = base::FeatureList::IsEnabled(
423 features::kDefaultEnableOopRasterization) ||
424 features::IsUsingSkiaRenderer();
Jonathan Backer06c419e12019-01-22 14:37:14425 if (use_gr_shader_cache)
426 CreateChannelCache(gpu::kGrShaderCacheClientId);
427 }
Mohsen Izadi0b9fbb62018-08-30 20:30:00428}
429
430void GpuHostImpl::DidFailInitialize() {
431 UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", false);
432 delegate_->DidFailInitialize();
433}
434
435void GpuHostImpl::DidCreateContextSuccessfully() {
436 delegate_->DidCreateContextSuccessfully();
437}
438
439void GpuHostImpl::DidCreateOffscreenContext(const GURL& url) {
440 urls_with_live_offscreen_contexts_.insert(url);
441}
442
443void GpuHostImpl::DidDestroyOffscreenContext(const GURL& url) {
444 // We only want to remove *one* of the entries in the multiset for this
445 // particular URL, so can't use the erase method taking a key.
446 auto candidate = urls_with_live_offscreen_contexts_.find(url);
447 if (candidate != urls_with_live_offscreen_contexts_.end())
448 urls_with_live_offscreen_contexts_.erase(candidate);
449}
450
451void GpuHostImpl::DidDestroyChannel(int32_t client_id) {
452 TRACE_EVENT0("gpu", "GpuHostImpl::DidDestroyChannel");
453 client_id_to_shader_cache_.erase(client_id);
454}
455
Bo Liu95570f32020-03-16 23:42:17456void GpuHostImpl::DidDestroyAllChannels() {
457 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
458 if (!channel_requests_.empty())
459 return;
460 constexpr base::TimeDelta kShutDownTimeout = base::TimeDelta::FromSeconds(10);
461 shutdown_timeout_.Start(FROM_HERE, kShutDownTimeout,
462 base::BindOnce(&GpuHostImpl::MaybeShutdownGpuProcess,
463 base::Unretained(this)));
464}
465
466void GpuHostImpl::MaybeShutdownGpuProcess() {
467 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
468 DCHECK(channel_requests_.empty());
469 delegate_->MaybeShutdownGpuProcess();
470}
471
Mohsen Izadi0b9fbb62018-08-30 20:30:00472void GpuHostImpl::DidLoseContext(bool offscreen,
473 gpu::error::ContextLostReason reason,
474 const GURL& active_url) {
475 // TODO(kbr): would be nice to see the "offscreen" flag too.
476 TRACE_EVENT2("gpu", "GpuHostImpl::DidLoseContext", "reason", reason, "url",
477 active_url.possibly_invalid_spec());
478
Patrick Todf5911c2020-05-12 19:31:42479 if (active_url.is_empty()) {
Mohsen Izadi0b9fbb62018-08-30 20:30:00480 return;
481 }
482
Mohsen Izadi312c6922018-09-07 14:21:36483 gpu::DomainGuilt guilt = gpu::DomainGuilt::kUnknown;
Mohsen Izadi0b9fbb62018-08-30 20:30:00484 switch (reason) {
485 case gpu::error::kGuilty:
Mohsen Izadi312c6922018-09-07 14:21:36486 guilt = gpu::DomainGuilt::kKnown;
Mohsen Izadi0b9fbb62018-08-30 20:30:00487 break;
488 // Treat most other error codes as though they had unknown provenance.
489 // In practice this doesn't affect the user experience. A lost context
490 // of either known or unknown guilt still causes user-level 3D APIs
491 // (e.g. WebGL) to be blocked on that domain until the user manually
492 // reenables them.
493 case gpu::error::kUnknown:
494 case gpu::error::kOutOfMemory:
495 case gpu::error::kMakeCurrentFailed:
496 case gpu::error::kGpuChannelLost:
497 case gpu::error::kInvalidGpuMessage:
498 break;
499 case gpu::error::kInnocent:
500 return;
501 }
502
503 delegate_->BlockDomainFrom3DAPIs(active_url, guilt);
504}
505
506void GpuHostImpl::DisableGpuCompositing() {
507 delegate_->DisableGpuCompositing();
508}
509
Jonah Ryan-Davisa54a3002020-12-08 17:34:50510void GpuHostImpl::DidUpdateGPUInfo(const gpu::GPUInfo& gpu_info) {
511 delegate_->DidUpdateGPUInfo(gpu_info);
512}
513
Mohsen Izadi50c28052018-09-07 00:32:14514#if defined(OS_WIN)
Maggie Chen8f177172020-02-11 00:02:28515void GpuHostImpl::DidUpdateOverlayInfo(const gpu::OverlayInfo& overlay_info) {
516 delegate_->DidUpdateOverlayInfo(overlay_info);
517}
518
Maggie Chen05364bf32020-06-03 08:34:06519void GpuHostImpl::DidUpdateHDRStatus(bool hdr_enabled) {
520 delegate_->DidUpdateHDRStatus(hdr_enabled);
521}
522
Mohsen Izadi0b9fbb62018-08-30 20:30:00523void GpuHostImpl::SetChildSurface(gpu::SurfaceHandle parent,
524 gpu::SurfaceHandle child) {
kylechar89341da82018-09-10 15:26:27525 if (pid_ != base::kNullProcessId) {
526 gfx::RenderingWindowManager::GetInstance()->RegisterChild(
527 parent, child, /*expected_child_process_id=*/pid_);
Mohsen Izadi0b9fbb62018-08-30 20:30:00528 }
Mohsen Izadi0b9fbb62018-08-30 20:30:00529}
Mohsen Izadi50c28052018-09-07 00:32:14530#endif // defined(OS_WIN)
Mohsen Izadi0b9fbb62018-08-30 20:30:00531
532void GpuHostImpl::StoreShaderToDisk(int32_t client_id,
533 const std::string& key,
534 const std::string& shader) {
535 TRACE_EVENT0("gpu", "GpuHostImpl::StoreShaderToDisk");
536 auto iter = client_id_to_shader_cache_.find(client_id);
537 // If the cache doesn't exist then this is an off the record profile.
538 if (iter == client_id_to_shader_cache_.end())
539 return;
540 std::string prefix = GetShaderPrefixKey();
541 iter->second->Cache(prefix + ":" + key, shader);
542}
543
544void GpuHostImpl::RecordLogMessage(int32_t severity,
545 const std::string& header,
546 const std::string& message) {
547 delegate_->RecordLogMessage(severity, header, message);
548}
549
550} // namespace viz