blob: 7fa32770729e97f2a46515c94f7dfa11f0142c23 [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
105 discardable_memory::mojom::DiscardableSharedMemoryManagerPtr
106 discardable_manager_ptr;
107 auto discardable_request = mojo::MakeRequest(&discardable_manager_ptr);
108 delegate_->BindDiscardableMemoryRequest(std::move(discardable_request));
109
110 DCHECK(GetFontRenderParams().Get());
kylechar80dd2aa2019-07-22 15:31:39111 viz_main_->CreateGpuService(gpu_service_remote_.BindNewPipeAndPassReceiver(),
112 gpu_host_receiver_.BindNewPipeAndPassRemote(),
113 std::move(discardable_manager_ptr),
114 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(
179 mojom::FrameSinkManagerRequest request,
180 mojom::FrameSinkManagerClientPtrInfo client) {
181 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);
191 params->frame_sink_manager = std::move(request);
192 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
209 // If GPU features are already blacklisted, no need to establish the channel.
210 if (!delegate_->GpuAccessAllowed()) {
211 DVLOG(1) << "GPU blacklisted, refusing to open a GPU channel.";
212 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
213 gpu::GpuFeatureInfo(),
214 EstablishChannelStatus::kGpuAccessDenied);
215 return;
216 }
217
218 if (gpu::IsReservedClientId(client_id)) {
219 // The display-compositor/GrShaderCache in the gpu process uses these
220 // special client ids.
221 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
222 gpu::GpuFeatureInfo(),
223 EstablishChannelStatus::kGpuAccessDenied);
224 return;
225 }
226
227 bool cache_shaders_on_disk =
228 delegate_->GetShaderCacheFactory()->Get(client_id) != nullptr;
229
230 channel_requests_.push(std::move(callback));
Shimi Zhang88ae9222019-07-19 16:54:16231 gpu_service_remote_->EstablishGpuChannel(
Mohsen Izadi0b9fbb62018-08-30 20:30:00232 client_id, client_tracing_id, is_gpu_host, cache_shaders_on_disk,
233 base::BindOnce(&GpuHostImpl::OnChannelEstablished,
234 weak_ptr_factory_.GetWeakPtr(), client_id));
235
Jonathan Backer06c419e12019-01-22 14:37:14236 if (!params_.disable_gpu_shader_disk_cache)
Mohsen Izadi0b9fbb62018-08-30 20:30:00237 CreateChannelCache(client_id);
Mohsen Izadi0b9fbb62018-08-30 20:30:00238}
239
240void GpuHostImpl::SendOutstandingReplies() {
241 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
242
Mohsen Izadibabed2b2018-08-31 01:37:39243 for (auto& handler : connection_error_handlers_)
244 std::move(handler).Run();
245 connection_error_handlers_.clear();
246
Mohsen Izadi0b9fbb62018-08-30 20:30:00247 // Send empty channel handles for all EstablishChannel requests.
248 while (!channel_requests_.empty()) {
249 auto callback = std::move(channel_requests_.front());
250 channel_requests_.pop();
251 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
252 gpu::GpuFeatureInfo(),
253 EstablishChannelStatus::kGpuHostInvalid);
254 }
255}
256
Mohsen Izadi63d85e72018-09-06 16:00:21257void GpuHostImpl::BindInterface(const std::string& interface_name,
258 mojo::ScopedMessagePipeHandle interface_pipe) {
259 delegate_->BindInterface(interface_name, std::move(interface_pipe));
260}
261
Ken Rockotb2928f32019-03-12 04:43:03262void GpuHostImpl::RunService(
263 const std::string& service_name,
264 mojo::PendingReceiver<service_manager::mojom::Service> receiver) {
265 delegate_->RunService(service_name, std::move(receiver));
266}
267
Mohsen Izadi0b9fbb62018-08-30 20:30:00268mojom::GpuService* GpuHostImpl::gpu_service() {
269 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Shimi Zhang88ae9222019-07-19 16:54:16270 DCHECK(gpu_service_remote_.is_bound());
271 return gpu_service_remote_.get();
Mohsen Izadi0b9fbb62018-08-30 20:30:00272}
273
Mohsen Izadi63d85e72018-09-06 16:00:21274#if defined(USE_OZONE)
Mohsen Izadia378a8f42019-08-02 02:34:19275
Mohsen Izadi63d85e72018-09-06 16:00:21276void GpuHostImpl::InitOzone() {
277 // Ozone needs to send the primary DRM device to GPU service as early as
278 // possible to ensure the latter always has a valid device.
279 // https://crbug.com/608839
Maksim Sisov2e064342018-10-03 10:35:06280 //
281 // The Ozone/Wayland requires mojo communication to be established to be
282 // functional with a separate gpu process. Thus, using the PlatformProperties,
283 // check if there is such a requirement.
Mohsen Izadia378a8f42019-08-02 02:34:19284 if (features::IsOzoneDrmMojo() ||
285 ui::OzonePlatform::GetInstance()->GetPlatformProperties().requires_mojo) {
Mohsen Izadi63d85e72018-09-06 16:00:21286 // TODO(rjkroege): Remove the legacy IPC code paths when no longer
287 // necessary. https://crbug.com/806092
288 auto interface_binder = base::BindRepeating(&GpuHostImpl::BindInterface,
289 weak_ptr_factory_.GetWeakPtr());
290 auto terminate_callback = base::BindOnce(&GpuHostImpl::TerminateGpuProcess,
291 weak_ptr_factory_.GetWeakPtr());
292
Mohsen Izadi6403b922019-05-22 20:13:34293 ui::OzonePlatform::GetInstance()
294 ->GetGpuPlatformSupportHost()
Saman Sami6f4086982019-06-28 19:09:55295 ->OnGpuServiceLaunched(params_.restart_id,
296 params_.main_thread_task_runner,
Mohsen Izadi6403b922019-05-22 20:13:34297 host_thread_task_runner_, interface_binder,
298 std::move(terminate_callback));
Mohsen Izadi63d85e72018-09-06 16:00:21299 } else {
300 auto send_callback = base::BindRepeating(
301 [](base::WeakPtr<GpuHostImpl> host, IPC::Message* message) {
302 if (host)
303 host->delegate_->SendGpuProcessMessage(message);
304 else
305 delete message;
306 },
307 weak_ptr_factory_.GetWeakPtr());
Mohsen Izadi6403b922019-05-22 20:13:34308 ui::OzonePlatform::GetInstance()
309 ->GetGpuPlatformSupportHost()
310 ->OnGpuProcessLaunched(params_.restart_id,
311 params_.main_thread_task_runner,
312 host_thread_task_runner_, send_callback);
Mohsen Izadi63d85e72018-09-06 16:00:21313 }
314}
315
316void GpuHostImpl::TerminateGpuProcess(const std::string& message) {
317 delegate_->TerminateGpuProcess(message);
318}
319
320#endif // defined(USE_OZONE)
321
Mohsen Izadi0b9fbb62018-08-30 20:30:00322std::string GpuHostImpl::GetShaderPrefixKey() {
323 if (shader_prefix_key_.empty()) {
324 const gpu::GPUInfo& info = delegate_->GetGPUInfo();
325 const gpu::GPUInfo::GPUDevice& active_gpu = info.active_gpu();
326
327 shader_prefix_key_ = params_.product + "-" + info.gl_vendor + "-" +
328 info.gl_renderer + "-" + active_gpu.driver_version +
329 "-" + active_gpu.driver_vendor;
330
331#if defined(OS_ANDROID)
332 std::string build_fp =
333 base::android::BuildInfo::GetInstance()->android_build_fp();
Mohsen Izadi0b9fbb62018-08-30 20:30:00334 shader_prefix_key_ += "-" + build_fp;
335#endif
336 }
337
338 return shader_prefix_key_;
339}
340
341void GpuHostImpl::LoadedShader(int32_t client_id,
342 const std::string& key,
343 const std::string& data) {
344 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
345
346 std::string prefix = GetShaderPrefixKey();
347 bool prefix_ok = !key.compare(0, prefix.length(), prefix);
348 UMA_HISTOGRAM_BOOLEAN("GPU.ShaderLoadPrefixOK", prefix_ok);
349 if (prefix_ok) {
350 // Remove the prefix from the key before load.
351 std::string key_no_prefix = key.substr(prefix.length() + 1);
Shimi Zhang88ae9222019-07-19 16:54:16352 gpu_service_remote_->LoadedShader(client_id, key_no_prefix, data);
Mohsen Izadi0b9fbb62018-08-30 20:30:00353 }
354}
355
356void GpuHostImpl::CreateChannelCache(int32_t client_id) {
357 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
358 TRACE_EVENT0("gpu", "GpuHostImpl::CreateChannelCache");
359
360 scoped_refptr<gpu::ShaderDiskCache> cache =
361 delegate_->GetShaderCacheFactory()->Get(client_id);
362 if (!cache)
363 return;
364
365 cache->set_shader_loaded_callback(base::BindRepeating(
366 &GpuHostImpl::LoadedShader, weak_ptr_factory_.GetWeakPtr(), client_id));
367
368 client_id_to_shader_cache_[client_id] = cache;
369}
370
371void GpuHostImpl::OnChannelEstablished(
372 int client_id,
373 mojo::ScopedMessagePipeHandle channel_handle) {
374 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
375 TRACE_EVENT0("gpu", "GpuHostImpl::OnChannelEstablished");
376
377 DCHECK(!channel_requests_.empty());
378 auto callback = std::move(channel_requests_.front());
379 channel_requests_.pop();
380
381 // Currently if any of the GPU features are blacklisted, we don't establish a
382 // GPU channel.
383 if (channel_handle.is_valid() && !delegate_->GpuAccessAllowed()) {
Shimi Zhang88ae9222019-07-19 16:54:16384 gpu_service_remote_->CloseChannel(client_id);
Mohsen Izadi0b9fbb62018-08-30 20:30:00385 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
386 gpu::GpuFeatureInfo(),
387 EstablishChannelStatus::kGpuAccessDenied);
388 RecordLogMessage(logging::LOG_WARNING, "WARNING",
389 "Hardware acceleration is unavailable.");
390 return;
391 }
392
393 std::move(callback).Run(std::move(channel_handle), delegate_->GetGPUInfo(),
394 delegate_->GetGpuFeatureInfo(),
395 EstablishChannelStatus::kSuccess);
396}
397
398void GpuHostImpl::DidInitialize(
399 const gpu::GPUInfo& gpu_info,
400 const gpu::GpuFeatureInfo& gpu_feature_info,
401 const base::Optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu,
402 const base::Optional<gpu::GpuFeatureInfo>&
Jonah Ryan-Davisa70577c2019-06-26 18:54:31403 gpu_feature_info_for_hardware_gpu,
404 const gpu::GpuExtraInfo& gpu_extra_info) {
Mohsen Izadi0b9fbb62018-08-30 20:30:00405 UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", true);
Mohsen Izadi0b9fbb62018-08-30 20:30:00406
407 // Set GPU driver bug workaround flags that are checked on the browser side.
408 wake_up_gpu_before_drawing_ =
409 gpu_feature_info.IsWorkaroundEnabled(gpu::WAKE_UP_GPU_BEFORE_DRAWING);
410 dont_disable_webgl_when_compositor_context_lost_ =
411 gpu_feature_info.IsWorkaroundEnabled(
412 gpu::DONT_DISABLE_WEBGL_WHEN_COMPOSITOR_CONTEXT_LOST);
413
Mohsen Izadif9505d82018-10-06 01:34:03414 delegate_->DidInitialize(gpu_info, gpu_feature_info,
Mohsen Izadi0b9fbb62018-08-30 20:30:00415 gpu_info_for_hardware_gpu,
Jonah Ryan-Davisa70577c2019-06-26 18:54:31416 gpu_feature_info_for_hardware_gpu, gpu_extra_info);
Jonathan Backer06c419e12019-01-22 14:37:14417
Jonathan Backer601e1a82019-01-22 17:42:00418 // Remove entries so that GPU process shader caches get populated on any
419 // GPU process start.
420 client_id_to_shader_cache_.clear();
421
Jonathan Backer06c419e12019-01-22 14:37:14422 if (!params_.disable_gpu_shader_disk_cache) {
kylecharb4f2e8b2019-03-05 13:56:47423 bool oopd_enabled = features::IsVizDisplayCompositorEnabled();
Jonathan Backer06c419e12019-01-22 14:37:14424 if (oopd_enabled)
425 CreateChannelCache(gpu::kInProcessCommandBufferClientId);
426
Peng Huang70021682019-09-18 19:42:28427 bool use_gr_shader_cache = base::FeatureList::IsEnabled(
428 features::kDefaultEnableOopRasterization) ||
429 features::IsUsingSkiaRenderer();
Jonathan Backer06c419e12019-01-22 14:37:14430 if (use_gr_shader_cache)
431 CreateChannelCache(gpu::kGrShaderCacheClientId);
432 }
Mohsen Izadi0b9fbb62018-08-30 20:30:00433}
434
435void GpuHostImpl::DidFailInitialize() {
436 UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", false);
437 delegate_->DidFailInitialize();
438}
439
440void GpuHostImpl::DidCreateContextSuccessfully() {
441 delegate_->DidCreateContextSuccessfully();
442}
443
444void GpuHostImpl::DidCreateOffscreenContext(const GURL& url) {
445 urls_with_live_offscreen_contexts_.insert(url);
446}
447
448void GpuHostImpl::DidDestroyOffscreenContext(const GURL& url) {
449 // We only want to remove *one* of the entries in the multiset for this
450 // particular URL, so can't use the erase method taking a key.
451 auto candidate = urls_with_live_offscreen_contexts_.find(url);
452 if (candidate != urls_with_live_offscreen_contexts_.end())
453 urls_with_live_offscreen_contexts_.erase(candidate);
454}
455
456void GpuHostImpl::DidDestroyChannel(int32_t client_id) {
457 TRACE_EVENT0("gpu", "GpuHostImpl::DidDestroyChannel");
458 client_id_to_shader_cache_.erase(client_id);
459}
460
461void GpuHostImpl::DidLoseContext(bool offscreen,
462 gpu::error::ContextLostReason reason,
463 const GURL& active_url) {
464 // TODO(kbr): would be nice to see the "offscreen" flag too.
465 TRACE_EVENT2("gpu", "GpuHostImpl::DidLoseContext", "reason", reason, "url",
466 active_url.possibly_invalid_spec());
467
468 if (!offscreen || active_url.is_empty()) {
469 // Assume that the loss of the compositor's or accelerated canvas'
470 // context is a serious event and blame the loss on all live
471 // offscreen contexts. This more robustly handles situations where
472 // the GPU process may not actually detect the context loss in the
473 // offscreen context. However, situations have been seen where the
474 // compositor's context can be lost due to driver bugs (as of this
475 // writing, on Android), so allow that possibility.
476 if (!dont_disable_webgl_when_compositor_context_lost_)
477 BlockLiveOffscreenContexts();
478 return;
479 }
480
Mohsen Izadi312c6922018-09-07 14:21:36481 gpu::DomainGuilt guilt = gpu::DomainGuilt::kUnknown;
Mohsen Izadi0b9fbb62018-08-30 20:30:00482 switch (reason) {
483 case gpu::error::kGuilty:
Mohsen Izadi312c6922018-09-07 14:21:36484 guilt = gpu::DomainGuilt::kKnown;
Mohsen Izadi0b9fbb62018-08-30 20:30:00485 break;
486 // Treat most other error codes as though they had unknown provenance.
487 // In practice this doesn't affect the user experience. A lost context
488 // of either known or unknown guilt still causes user-level 3D APIs
489 // (e.g. WebGL) to be blocked on that domain until the user manually
490 // reenables them.
491 case gpu::error::kUnknown:
492 case gpu::error::kOutOfMemory:
493 case gpu::error::kMakeCurrentFailed:
494 case gpu::error::kGpuChannelLost:
495 case gpu::error::kInvalidGpuMessage:
496 break;
497 case gpu::error::kInnocent:
498 return;
499 }
500
501 delegate_->BlockDomainFrom3DAPIs(active_url, guilt);
502}
503
504void GpuHostImpl::DisableGpuCompositing() {
505 delegate_->DisableGpuCompositing();
506}
507
Mohsen Izadi50c28052018-09-07 00:32:14508#if defined(OS_WIN)
Mohsen Izadi0b9fbb62018-08-30 20:30:00509void GpuHostImpl::SetChildSurface(gpu::SurfaceHandle parent,
510 gpu::SurfaceHandle child) {
kylechar89341da82018-09-10 15:26:27511 if (pid_ != base::kNullProcessId) {
512 gfx::RenderingWindowManager::GetInstance()->RegisterChild(
513 parent, child, /*expected_child_process_id=*/pid_);
Mohsen Izadi0b9fbb62018-08-30 20:30:00514 }
Mohsen Izadi0b9fbb62018-08-30 20:30:00515}
Mohsen Izadi50c28052018-09-07 00:32:14516#endif // defined(OS_WIN)
Mohsen Izadi0b9fbb62018-08-30 20:30:00517
518void GpuHostImpl::StoreShaderToDisk(int32_t client_id,
519 const std::string& key,
520 const std::string& shader) {
521 TRACE_EVENT0("gpu", "GpuHostImpl::StoreShaderToDisk");
522 auto iter = client_id_to_shader_cache_.find(client_id);
523 // If the cache doesn't exist then this is an off the record profile.
524 if (iter == client_id_to_shader_cache_.end())
525 return;
526 std::string prefix = GetShaderPrefixKey();
527 iter->second->Cache(prefix + ":" + key, shader);
528}
529
530void GpuHostImpl::RecordLogMessage(int32_t severity,
531 const std::string& header,
532 const std::string& message) {
533 delegate_->RecordLogMessage(severity, header, message);
534}
535
536} // namespace viz