blob: 10603fc327d0a411ed137479ce552cb21fe0a2ef [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
9#include "base/bind_helpers.h"
10#include "base/command_line.h"
11#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"
20#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"
25#include "ipc/ipc_channel.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);
47 const base::Optional<gfx::FontRenderParams>& Get();
48
49 private:
50 friend class base::NoDestructor<FontRenderParams>;
51
52 FontRenderParams();
53 ~FontRenderParams();
54
55 THREAD_CHECKER(thread_checker_);
56 base::Optional<gfx::FontRenderParams> params_;
57
58 DISALLOW_COPY_AND_ASSIGN(FontRenderParams);
59};
60
61void FontRenderParams::Set(const gfx::FontRenderParams& params) {
62 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
63 params_ = params;
64}
65
66const base::Optional<gfx::FontRenderParams>& FontRenderParams::Get() {
67 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
68 return params_;
69}
70
71FontRenderParams::FontRenderParams() = default;
72
73FontRenderParams::~FontRenderParams() {
74 NOTREACHED();
75}
76
77FontRenderParams& GetFontRenderParams() {
78 static base::NoDestructor<FontRenderParams> instance;
79 return *instance;
80}
81
Mohsen Izadi63d85e72018-09-06 16:00:2182#if defined(USE_OZONE)
83// Helper to register Mus/conventional thread bouncers for ozone startup.
84void OzoneRegisterStartupCallbackHelper(
85 scoped_refptr<base::SingleThreadTaskRunner> host_thread_task_runner,
86 base::OnceCallback<void(ui::OzonePlatform*)> callback) {
87 // The callback registered in ozone can be called in any thread. So use an
88 // intermediary callback that bounces to the GpuHost thread if needed, before
89 // running the callback.
90 auto bounce_callback = base::BindOnce(
91 [](base::SingleThreadTaskRunner* host_thread_task_runner,
92 base::OnceCallback<void(ui::OzonePlatform*)> callback,
93 ui::OzonePlatform* platform) {
94 if (host_thread_task_runner->BelongsToCurrentThread()) {
95 std::move(callback).Run(platform);
96 } else {
97 host_thread_task_runner->PostTask(
98 FROM_HERE, base::BindOnce(std::move(callback), platform));
99 }
100 },
101 base::RetainedRef(host_thread_task_runner), std::move(callback));
102 ui::OzonePlatform::RegisterStartupCallback(std::move(bounce_callback));
103}
104#endif // defined(USE_OZONE)
105
Mohsen Izadi0b9fbb62018-08-30 20:30:00106} // namespace
107
108GpuHostImpl::InitParams::InitParams() = default;
109
110GpuHostImpl::InitParams::InitParams(InitParams&&) = default;
111
112GpuHostImpl::InitParams::~InitParams() = default;
113
114GpuHostImpl::GpuHostImpl(Delegate* delegate,
115 IPC::Channel* channel,
116 InitParams params)
117 : delegate_(delegate),
118 channel_(channel),
119 params_(std::move(params)),
Mohsen Izadi63d85e72018-09-06 16:00:21120 host_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
Mohsen Izadi0b9fbb62018-08-30 20:30:00121 gpu_host_binding_(this),
122 weak_ptr_factory_(this) {
123 DCHECK(delegate_);
124 DCHECK(channel_);
125 channel_->GetAssociatedInterfaceSupport()->GetRemoteAssociatedInterface(
126 &viz_main_ptr_);
127 mojom::GpuHostPtr host_proxy;
128 gpu_host_binding_.Bind(mojo::MakeRequest(&host_proxy));
129
130 discardable_memory::mojom::DiscardableSharedMemoryManagerPtr
131 discardable_manager_ptr;
132 auto discardable_request = mojo::MakeRequest(&discardable_manager_ptr);
133 delegate_->BindDiscardableMemoryRequest(std::move(discardable_request));
134
135 DCHECK(GetFontRenderParams().Get());
136 viz_main_ptr_->CreateGpuService(
137 mojo::MakeRequest(&gpu_service_ptr_), std::move(host_proxy),
138 std::move(discardable_manager_ptr), activity_flags_.CloneHandle(),
139 GetFontRenderParams().Get()->subpixel_rendering);
Mohsen Izadi63d85e72018-09-06 16:00:21140
141#if defined(USE_OZONE)
142 InitOzone();
143#endif // defined(USE_OZONE)
Mohsen Izadi0b9fbb62018-08-30 20:30:00144}
145
146GpuHostImpl::~GpuHostImpl() = default;
147
148// static
149void GpuHostImpl::InitFontRenderParams(const gfx::FontRenderParams& params) {
150 DCHECK(!GetFontRenderParams().Get());
151 GetFontRenderParams().Set(params);
152}
153
154void GpuHostImpl::OnProcessLaunched(base::ProcessId pid) {
155 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
156 DCHECK_EQ(base::kNullProcessId, pid_);
157 DCHECK_NE(base::kNullProcessId, pid);
158 pid_ = pid;
159}
160
161void GpuHostImpl::OnProcessCrashed() {
162 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
163
164 // If the GPU process crashed while compiling a shader, we may have invalid
165 // cached binaries. Completely clear the shader cache to force shader binaries
166 // to be re-created.
167 if (activity_flags_.IsFlagSet(
168 gpu::ActivityFlagsBase::FLAG_LOADING_PROGRAM_BINARY)) {
169 auto* shader_cache_factory = delegate_->GetShaderCacheFactory();
170 for (auto cache_key : client_id_to_shader_cache_) {
171 // This call will temporarily extend the lifetime of the cache (kept
172 // alive in the factory), and may drop loads of cached shader binaries if
173 // it takes a while to complete. As we are intentionally dropping all
174 // binaries, this behavior is fine.
175 shader_cache_factory->ClearByClientId(
176 cache_key.first, base::Time(), base::Time::Max(), base::DoNothing());
177 }
178 }
179}
180
Mohsen Izadibabed2b2018-08-31 01:37:39181void GpuHostImpl::AddConnectionErrorHandler(base::OnceClosure handler) {
182 connection_error_handlers_.push_back(std::move(handler));
183}
184
Mohsen Izadi0b9fbb62018-08-30 20:30:00185void GpuHostImpl::BlockLiveOffscreenContexts() {
186 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
187
188 for (auto iter = urls_with_live_offscreen_contexts_.begin();
189 iter != urls_with_live_offscreen_contexts_.end(); ++iter) {
190 delegate_->BlockDomainFrom3DAPIs(*iter, Delegate::DomainGuilt::kUnknown);
191 }
192}
193
194void GpuHostImpl::ConnectFrameSinkManager(
195 mojom::FrameSinkManagerRequest request,
196 mojom::FrameSinkManagerClientPtrInfo client) {
197 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
198 TRACE_EVENT0("gpu", "GpuHostImpl::ConnectFrameSinkManager");
199
200 mojom::FrameSinkManagerParamsPtr params =
201 mojom::FrameSinkManagerParams::New();
202 params->restart_id = params_.restart_id;
203 params->use_activation_deadline =
204 params_.deadline_to_synchronize_surfaces.has_value();
205 params->activation_deadline_in_frames =
206 params_.deadline_to_synchronize_surfaces.value_or(0u);
207 params->frame_sink_manager = std::move(request);
208 params->frame_sink_manager_client = std::move(client);
209 viz_main_ptr_->CreateFrameSinkManager(std::move(params));
210}
211
212void GpuHostImpl::EstablishGpuChannel(int client_id,
213 uint64_t client_tracing_id,
214 bool is_gpu_host,
215 EstablishChannelCallback callback) {
216 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
217 TRACE_EVENT0("gpu", "GpuHostImpl::EstablishGpuChannel");
218
219 // If GPU features are already blacklisted, no need to establish the channel.
220 if (!delegate_->GpuAccessAllowed()) {
221 DVLOG(1) << "GPU blacklisted, refusing to open a GPU channel.";
222 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
223 gpu::GpuFeatureInfo(),
224 EstablishChannelStatus::kGpuAccessDenied);
225 return;
226 }
227
228 if (gpu::IsReservedClientId(client_id)) {
229 // The display-compositor/GrShaderCache in the gpu process uses these
230 // special client ids.
231 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
232 gpu::GpuFeatureInfo(),
233 EstablishChannelStatus::kGpuAccessDenied);
234 return;
235 }
236
237 bool cache_shaders_on_disk =
238 delegate_->GetShaderCacheFactory()->Get(client_id) != nullptr;
239
240 channel_requests_.push(std::move(callback));
241 gpu_service_ptr_->EstablishGpuChannel(
242 client_id, client_tracing_id, is_gpu_host, cache_shaders_on_disk,
243 base::BindOnce(&GpuHostImpl::OnChannelEstablished,
244 weak_ptr_factory_.GetWeakPtr(), client_id));
245
246 if (!params_.disable_gpu_shader_disk_cache) {
247 CreateChannelCache(client_id);
248
249 bool oopd_enabled =
250 base::FeatureList::IsEnabled(features::kVizDisplayCompositor);
251 if (oopd_enabled)
252 CreateChannelCache(gpu::kInProcessCommandBufferClientId);
253
254 bool oopr_enabled =
255 base::FeatureList::IsEnabled(features::kDefaultEnableOopRasterization);
256 if (oopr_enabled)
257 CreateChannelCache(gpu::kGrShaderCacheClientId);
258 }
259}
260
261void GpuHostImpl::SendOutstandingReplies() {
262 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
263
Mohsen Izadibabed2b2018-08-31 01:37:39264 for (auto& handler : connection_error_handlers_)
265 std::move(handler).Run();
266 connection_error_handlers_.clear();
267
Mohsen Izadi0b9fbb62018-08-30 20:30:00268 // Send empty channel handles for all EstablishChannel requests.
269 while (!channel_requests_.empty()) {
270 auto callback = std::move(channel_requests_.front());
271 channel_requests_.pop();
272 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
273 gpu::GpuFeatureInfo(),
274 EstablishChannelStatus::kGpuHostInvalid);
275 }
276}
277
Mohsen Izadi63d85e72018-09-06 16:00:21278void GpuHostImpl::BindInterface(const std::string& interface_name,
279 mojo::ScopedMessagePipeHandle interface_pipe) {
280 delegate_->BindInterface(interface_name, std::move(interface_pipe));
281}
282
Mohsen Izadi0b9fbb62018-08-30 20:30:00283mojom::GpuService* GpuHostImpl::gpu_service() {
284 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
285 DCHECK(gpu_service_ptr_.is_bound());
286 return gpu_service_ptr_.get();
287}
288
Mohsen Izadi63d85e72018-09-06 16:00:21289#if defined(USE_OZONE)
290void GpuHostImpl::InitOzone() {
291 // Ozone needs to send the primary DRM device to GPU service as early as
292 // possible to ensure the latter always has a valid device.
293 // https://crbug.com/608839
294 // If the OzonePlatform is not created yet, defer the callback until
295 // OzonePlatform instance is created.
296 bool using_mojo = true;
297#if defined(OS_CHROMEOS)
298 using_mojo = features::IsOzoneDrmMojo();
299#endif
300 if (using_mojo) {
301 // TODO(rjkroege): Remove the legacy IPC code paths when no longer
302 // necessary. https://crbug.com/806092
303 auto interface_binder = base::BindRepeating(&GpuHostImpl::BindInterface,
304 weak_ptr_factory_.GetWeakPtr());
305 auto terminate_callback = base::BindOnce(&GpuHostImpl::TerminateGpuProcess,
306 weak_ptr_factory_.GetWeakPtr());
307
308 auto startup_callback = base::BindOnce(
309 [](const base::RepeatingCallback<void(const std::string&,
310 mojo::ScopedMessagePipeHandle)>&
311 interface_binder,
312 base::OnceCallback<void(const std::string&)> terminate_callback,
313 scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
314 scoped_refptr<base::SingleThreadTaskRunner> host_thread_task_runner,
315 ui::OzonePlatform* platform) {
316 DCHECK(host_thread_task_runner->BelongsToCurrentThread());
317 platform->GetGpuPlatformSupportHost()->OnGpuServiceLaunched(
318 main_thread_task_runner, host_thread_task_runner,
319 interface_binder, std::move(terminate_callback));
320 },
321 interface_binder, std::move(terminate_callback),
322 params_.main_thread_task_runner, host_thread_task_runner_);
323 OzoneRegisterStartupCallbackHelper(host_thread_task_runner_,
324 std::move(startup_callback));
325 } else {
326 auto send_callback = base::BindRepeating(
327 [](base::WeakPtr<GpuHostImpl> host, IPC::Message* message) {
328 if (host)
329 host->delegate_->SendGpuProcessMessage(message);
330 else
331 delete message;
332 },
333 weak_ptr_factory_.GetWeakPtr());
334 // Create the callback that should run on the current thread.
335 auto startup_callback = base::BindOnce(
336 [](int host_id,
337 const base::RepeatingCallback<void(IPC::Message*)>& send_callback,
338 scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
339 scoped_refptr<base::SingleThreadTaskRunner> host_thread_task_runner,
340 ui::OzonePlatform* platform) {
341 DCHECK(host_thread_task_runner->BelongsToCurrentThread());
342 platform->GetGpuPlatformSupportHost()->OnGpuProcessLaunched(
343 host_id, main_thread_task_runner, host_thread_task_runner,
344 send_callback);
345 },
346 params_.restart_id, send_callback, params_.main_thread_task_runner,
347 host_thread_task_runner_);
348 OzoneRegisterStartupCallbackHelper(host_thread_task_runner_,
349 std::move(startup_callback));
350 }
351}
352
353void GpuHostImpl::TerminateGpuProcess(const std::string& message) {
354 delegate_->TerminateGpuProcess(message);
355}
356
357#endif // defined(USE_OZONE)
358
Mohsen Izadi0b9fbb62018-08-30 20:30:00359std::string GpuHostImpl::GetShaderPrefixKey() {
360 if (shader_prefix_key_.empty()) {
361 const gpu::GPUInfo& info = delegate_->GetGPUInfo();
362 const gpu::GPUInfo::GPUDevice& active_gpu = info.active_gpu();
363
364 shader_prefix_key_ = params_.product + "-" + info.gl_vendor + "-" +
365 info.gl_renderer + "-" + active_gpu.driver_version +
366 "-" + active_gpu.driver_vendor;
367
368#if defined(OS_ANDROID)
369 std::string build_fp =
370 base::android::BuildInfo::GetInstance()->android_build_fp();
Mohsen Izadi0b9fbb62018-08-30 20:30:00371 shader_prefix_key_ += "-" + build_fp;
372#endif
373 }
374
375 return shader_prefix_key_;
376}
377
378void GpuHostImpl::LoadedShader(int32_t client_id,
379 const std::string& key,
380 const std::string& data) {
381 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
382
383 std::string prefix = GetShaderPrefixKey();
384 bool prefix_ok = !key.compare(0, prefix.length(), prefix);
385 UMA_HISTOGRAM_BOOLEAN("GPU.ShaderLoadPrefixOK", prefix_ok);
386 if (prefix_ok) {
387 // Remove the prefix from the key before load.
388 std::string key_no_prefix = key.substr(prefix.length() + 1);
389 gpu_service_ptr_->LoadedShader(client_id, key_no_prefix, data);
390 }
391}
392
393void GpuHostImpl::CreateChannelCache(int32_t client_id) {
394 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
395 TRACE_EVENT0("gpu", "GpuHostImpl::CreateChannelCache");
396
397 scoped_refptr<gpu::ShaderDiskCache> cache =
398 delegate_->GetShaderCacheFactory()->Get(client_id);
399 if (!cache)
400 return;
401
402 cache->set_shader_loaded_callback(base::BindRepeating(
403 &GpuHostImpl::LoadedShader, weak_ptr_factory_.GetWeakPtr(), client_id));
404
405 client_id_to_shader_cache_[client_id] = cache;
406}
407
408void GpuHostImpl::OnChannelEstablished(
409 int client_id,
410 mojo::ScopedMessagePipeHandle channel_handle) {
411 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
412 TRACE_EVENT0("gpu", "GpuHostImpl::OnChannelEstablished");
413
414 DCHECK(!channel_requests_.empty());
415 auto callback = std::move(channel_requests_.front());
416 channel_requests_.pop();
417
418 // Currently if any of the GPU features are blacklisted, we don't establish a
419 // GPU channel.
420 if (channel_handle.is_valid() && !delegate_->GpuAccessAllowed()) {
421 gpu_service_ptr_->CloseChannel(client_id);
422 std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
423 gpu::GpuFeatureInfo(),
424 EstablishChannelStatus::kGpuAccessDenied);
425 RecordLogMessage(logging::LOG_WARNING, "WARNING",
426 "Hardware acceleration is unavailable.");
427 return;
428 }
429
430 std::move(callback).Run(std::move(channel_handle), delegate_->GetGPUInfo(),
431 delegate_->GetGpuFeatureInfo(),
432 EstablishChannelStatus::kSuccess);
433}
434
435void GpuHostImpl::DidInitialize(
436 const gpu::GPUInfo& gpu_info,
437 const gpu::GpuFeatureInfo& gpu_feature_info,
438 const base::Optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu,
439 const base::Optional<gpu::GpuFeatureInfo>&
440 gpu_feature_info_for_hardware_gpu) {
441 UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", true);
442 initialized_ = true;
443
444 // Set GPU driver bug workaround flags that are checked on the browser side.
445 wake_up_gpu_before_drawing_ =
446 gpu_feature_info.IsWorkaroundEnabled(gpu::WAKE_UP_GPU_BEFORE_DRAWING);
447 dont_disable_webgl_when_compositor_context_lost_ =
448 gpu_feature_info.IsWorkaroundEnabled(
449 gpu::DONT_DISABLE_WEBGL_WHEN_COMPOSITOR_CONTEXT_LOST);
450
451 delegate_->UpdateGpuInfo(gpu_info, gpu_feature_info,
452 gpu_info_for_hardware_gpu,
453 gpu_feature_info_for_hardware_gpu);
454}
455
456void GpuHostImpl::DidFailInitialize() {
457 UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", false);
458 delegate_->DidFailInitialize();
459}
460
461void GpuHostImpl::DidCreateContextSuccessfully() {
462 delegate_->DidCreateContextSuccessfully();
463}
464
465void GpuHostImpl::DidCreateOffscreenContext(const GURL& url) {
466 urls_with_live_offscreen_contexts_.insert(url);
467}
468
469void GpuHostImpl::DidDestroyOffscreenContext(const GURL& url) {
470 // We only want to remove *one* of the entries in the multiset for this
471 // particular URL, so can't use the erase method taking a key.
472 auto candidate = urls_with_live_offscreen_contexts_.find(url);
473 if (candidate != urls_with_live_offscreen_contexts_.end())
474 urls_with_live_offscreen_contexts_.erase(candidate);
475}
476
477void GpuHostImpl::DidDestroyChannel(int32_t client_id) {
478 TRACE_EVENT0("gpu", "GpuHostImpl::DidDestroyChannel");
479 client_id_to_shader_cache_.erase(client_id);
480}
481
482void GpuHostImpl::DidLoseContext(bool offscreen,
483 gpu::error::ContextLostReason reason,
484 const GURL& active_url) {
485 // TODO(kbr): would be nice to see the "offscreen" flag too.
486 TRACE_EVENT2("gpu", "GpuHostImpl::DidLoseContext", "reason", reason, "url",
487 active_url.possibly_invalid_spec());
488
489 if (!offscreen || active_url.is_empty()) {
490 // Assume that the loss of the compositor's or accelerated canvas'
491 // context is a serious event and blame the loss on all live
492 // offscreen contexts. This more robustly handles situations where
493 // the GPU process may not actually detect the context loss in the
494 // offscreen context. However, situations have been seen where the
495 // compositor's context can be lost due to driver bugs (as of this
496 // writing, on Android), so allow that possibility.
497 if (!dont_disable_webgl_when_compositor_context_lost_)
498 BlockLiveOffscreenContexts();
499 return;
500 }
501
502 Delegate::DomainGuilt guilt = Delegate::DomainGuilt::kUnknown;
503 switch (reason) {
504 case gpu::error::kGuilty:
505 guilt = Delegate::DomainGuilt::kKnown;
506 break;
507 // Treat most other error codes as though they had unknown provenance.
508 // In practice this doesn't affect the user experience. A lost context
509 // of either known or unknown guilt still causes user-level 3D APIs
510 // (e.g. WebGL) to be blocked on that domain until the user manually
511 // reenables them.
512 case gpu::error::kUnknown:
513 case gpu::error::kOutOfMemory:
514 case gpu::error::kMakeCurrentFailed:
515 case gpu::error::kGpuChannelLost:
516 case gpu::error::kInvalidGpuMessage:
517 break;
518 case gpu::error::kInnocent:
519 return;
520 }
521
522 delegate_->BlockDomainFrom3DAPIs(active_url, guilt);
523}
524
525void GpuHostImpl::DisableGpuCompositing() {
526 delegate_->DisableGpuCompositing();
527}
528
Mohsen Izadi50c28052018-09-07 00:32:14529#if defined(OS_WIN)
Mohsen Izadi0b9fbb62018-08-30 20:30:00530void GpuHostImpl::SetChildSurface(gpu::SurfaceHandle parent,
531 gpu::SurfaceHandle child) {
Mohsen Izadi0b9fbb62018-08-30 20:30:00532 constexpr char kBadMessageError[] = "Bad parenting request from gpu process.";
533 if (!params_.in_process) {
534 DWORD parent_process_id = 0;
535 DWORD parent_thread_id =
536 ::GetWindowThreadProcessId(parent, &parent_process_id);
537 if (!parent_thread_id || parent_process_id != ::GetCurrentProcessId()) {
538 LOG(ERROR) << kBadMessageError;
539 return;
540 }
541
542 DWORD child_process_id = 0;
543 DWORD child_thread_id =
544 ::GetWindowThreadProcessId(child, &child_process_id);
545 if (!child_thread_id || child_process_id != pid_) {
546 LOG(ERROR) << kBadMessageError;
547 return;
548 }
549 }
550
551 if (!gfx::RenderingWindowManager::GetInstance()->RegisterChild(parent,
552 child)) {
553 LOG(ERROR) << kBadMessageError;
554 }
Mohsen Izadi0b9fbb62018-08-30 20:30:00555}
Mohsen Izadi50c28052018-09-07 00:32:14556#endif // defined(OS_WIN)
Mohsen Izadi0b9fbb62018-08-30 20:30:00557
558void GpuHostImpl::StoreShaderToDisk(int32_t client_id,
559 const std::string& key,
560 const std::string& shader) {
561 TRACE_EVENT0("gpu", "GpuHostImpl::StoreShaderToDisk");
562 auto iter = client_id_to_shader_cache_.find(client_id);
563 // If the cache doesn't exist then this is an off the record profile.
564 if (iter == client_id_to_shader_cache_.end())
565 return;
566 std::string prefix = GetShaderPrefixKey();
567 iter->second->Cache(prefix + ":" + key, shader);
568}
569
570void GpuHostImpl::RecordLogMessage(int32_t severity,
571 const std::string& header,
572 const std::string& message) {
573 delegate_->RecordLogMessage(severity, header, message);
574}
575
576} // namespace viz