1 // Copyright 2016 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/service/gl/gpu_service_impl.h"
6
7 #include <memory>
8 #include <string>
9 #include <utility>
10 #include <vector>
11
12 #include "base/bind.h"
13 #include "base/command_line.h"
14 #include "base/feature_list.h"
15 #include "base/no_destructor.h"
16 #include "base/task/post_task.h"
17 #include "base/task/thread_pool.h"
18 #include "base/task_runner_util.h"
19 #include "base/threading/thread_task_runner_handle.h"
20 #include "build/build_config.h"
21 #include "components/viz/common/features.h"
22 #include "components/viz/common/gpu/metal_context_provider.h"
23 #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
24 #include "gpu/command_buffer/service/gpu_switches.h"
25 #include "gpu/command_buffer/service/scheduler.h"
26 #include "gpu/command_buffer/service/shared_context_state.h"
27 #include "gpu/command_buffer/service/skia_utils.h"
28 #include "gpu/command_buffer/service/sync_point_manager.h"
29 #include "gpu/config/dx_diag_node.h"
30 #include "gpu/config/gpu_finch_features.h"
31 #include "gpu/config/gpu_info_collector.h"
32 #include "gpu/config/gpu_switches.h"
33 #include "gpu/config/gpu_util.h"
34 #include "gpu/ipc/common/gpu_client_ids.h"
35 #include "gpu/ipc/common/gpu_memory_buffer_support.h"
36 #include "gpu/ipc/common/gpu_peak_memory.h"
37 #include "gpu/ipc/common/memory_stats.h"
38 #include "gpu/ipc/in_process_command_buffer.h"
39 #include "gpu/ipc/service/gpu_channel.h"
40 #include "gpu/ipc/service/gpu_channel_manager.h"
41 #include "gpu/ipc/service/gpu_memory_buffer_factory.h"
42 #include "gpu/ipc/service/gpu_watchdog_thread.h"
43 #include "gpu/ipc/service/image_decode_accelerator_worker.h"
44 #include "gpu/vulkan/buildflags.h"
45 #include "ipc/ipc_channel_handle.h"
46 #include "ipc/ipc_sync_channel.h"
47 #include "ipc/ipc_sync_message_filter.h"
48 #include "media/gpu/buildflags.h"
49 #include "media/gpu/gpu_video_accelerator_util.h"
50 #include "media/gpu/gpu_video_encode_accelerator_factory.h"
51 #include "media/gpu/ipc/service/gpu_video_decode_accelerator.h"
52 #include "media/gpu/ipc/service/media_gpu_channel_manager.h"
53 #include "media/mojo/services/mojo_video_encode_accelerator_provider.h"
54 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
55 #include "skia/buildflags.h"
56 #include "third_party/skia/include/gpu/GrDirectContext.h"
57 #include "third_party/skia/include/gpu/gl/GrGLAssembleInterface.h"
58 #include "third_party/skia/include/gpu/gl/GrGLInterface.h"
59 #include "ui/gl/gl_context.h"
60 #include "ui/gl/gl_implementation.h"
61 #include "ui/gl/gl_switches.h"
62 #include "ui/gl/gl_utils.h"
63 #include "ui/gl/gpu_switching_manager.h"
64 #include "ui/gl/init/create_gr_gl_interface.h"
65 #include "ui/gl/init/gl_factory.h"
66 #include "url/gurl.h"
67
68 #if BUILDFLAG(USE_VAAPI)
69 #include "media/gpu/vaapi/vaapi_image_decode_accelerator_worker.h"
70 #endif // BUILDFLAG(USE_VAAPI)
71
72 #if defined(OS_ANDROID)
73 #include "components/viz/service/gl/throw_uncaught_exception.h"
74 #include "media/base/android/media_codec_util.h"
75 #endif
76
77 #if defined(OS_CHROMEOS)
78 #include "components/arc/video_accelerator/gpu_arc_video_decode_accelerator.h"
79 #include "components/arc/video_accelerator/gpu_arc_video_encode_accelerator.h"
80 #include "components/arc/video_accelerator/gpu_arc_video_protected_buffer_allocator.h"
81 #include "components/arc/video_accelerator/protected_buffer_manager.h"
82 #include "components/arc/video_accelerator/protected_buffer_manager_proxy.h"
83 #include "components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.h"
84 #include "components/chromeos_camera/mojo_jpeg_encode_accelerator_service.h"
85 #include "components/chromeos_camera/mojo_mjpeg_decode_accelerator_service.h"
86 #endif // defined(OS_CHROMEOS)
87
88 #if defined(OS_WIN)
89 #include "ui/gl/direct_composition_surface_win.h"
90 #endif
91
92 #if defined(OS_APPLE)
93 #include "ui/base/cocoa/quartz_util.h"
94 #endif
95
96 #if BUILDFLAG(SKIA_USE_DAWN)
97 #include "components/viz/common/gpu/dawn_context_provider.h"
98 #endif
99
100 #if BUILDFLAG(CLANG_PROFILING_INSIDE_SANDBOX)
101 #include "base/test/clang_profiling.h"
102 #endif
103
104 #if BUILDFLAG(ENABLE_VULKAN)
105 #include "components/viz/common/gpu/vulkan_context_provider.h"
106 #include "components/viz/common/gpu/vulkan_in_process_context_provider.h"
107 #endif
108
109 namespace viz {
110
111 namespace {
112
113 using LogCallback = base::RepeatingCallback<
114 void(int severity, const std::string& header, const std::string& message)>;
115
116 struct LogMessage {
LogMessageviz::__anon85a7cb450111::LogMessage117 LogMessage(int severity,
118 const std::string& header,
119 const std::string& message)
120 : severity(severity),
121 header(std::move(header)),
122 message(std::move(message)) {}
123 const int severity;
124 const std::string header;
125 const std::string message;
126 };
127
128 // Forward declare log handlers so they can be used within LogMessageManager.
129 bool PreInitializeLogHandler(int severity,
130 const char* file,
131 int line,
132 size_t message_start,
133 const std::string& message);
134 bool PostInitializeLogHandler(int severity,
135 const char* file,
136 int line,
137 size_t message_start,
138 const std::string& message);
139
140 // Class which manages LOG() message forwarding before and after GpuServiceImpl
141 // InitializeWithHost(). Prior to initialize, log messages are deferred and kept
142 // within the class. During initialize, InstallPostInitializeLogHandler() will
143 // be called to flush deferred messages and route new ones directly to GpuHost.
144 class LogMessageManager {
145 public:
146 LogMessageManager() = default;
147 ~LogMessageManager() = delete;
148
149 // Queues a deferred LOG() message into |deferred_messages_| unless
150 // |log_callback_| has been set -- in which case RouteMessage() is called.
AddDeferredMessage(int severity,const std::string & header,const std::string & message)151 void AddDeferredMessage(int severity,
152 const std::string& header,
153 const std::string& message) {
154 base::AutoLock lock(message_lock_);
155 // During InstallPostInitializeLogHandler() there's a brief window where a
156 // call into this function may be waiting on |message_lock_|, so we need to
157 // check if |log_callback_| was set once we get the lock.
158 if (log_callback_) {
159 RouteMessage(severity, std::move(header), std::move(message));
160 return;
161 }
162
163 // Otherwise just queue the message for InstallPostInitializeLogHandler() to
164 // forward later.
165 deferred_messages_.emplace_back(severity, std::move(header),
166 std::move(message));
167 }
168
169 // Used after InstallPostInitializeLogHandler() to route messages directly to
170 // |log_callback_|; avoids the need for a global lock.
RouteMessage(int severity,const std::string & header,const std::string & message)171 void RouteMessage(int severity,
172 const std::string& header,
173 const std::string& message) {
174 log_callback_.Run(severity, std::move(header), std::move(message));
175 }
176
177 // If InstallPostInitializeLogHandler() will never be called, this method is
178 // called prior to process exit to ensure logs are forwarded.
FlushMessages(mojom::GpuHost * gpu_host)179 void FlushMessages(mojom::GpuHost* gpu_host) {
180 base::AutoLock lock(message_lock_);
181 for (auto& log : deferred_messages_) {
182 gpu_host->RecordLogMessage(log.severity, std::move(log.header),
183 std::move(log.message));
184 }
185 deferred_messages_.clear();
186 }
187
188 // Used prior to InitializeWithHost() during GpuMain startup to ensure logs
189 // aren't lost before initialize.
InstallPreInitializeLogHandler()190 void InstallPreInitializeLogHandler() {
191 DCHECK(!log_callback_);
192 logging::SetLogMessageHandler(PreInitializeLogHandler);
193 }
194
195 // Called by InitializeWithHost() to take over logging from the
196 // PostInitializeLogHandler(). Flushes all deferred messages.
InstallPostInitializeLogHandler(LogCallback log_callback)197 void InstallPostInitializeLogHandler(LogCallback log_callback) {
198 base::AutoLock lock(message_lock_);
199 DCHECK(!log_callback_);
200 log_callback_ = std::move(log_callback);
201 for (auto& log : deferred_messages_)
202 RouteMessage(log.severity, std::move(log.header), std::move(log.message));
203 deferred_messages_.clear();
204 logging::SetLogMessageHandler(PostInitializeLogHandler);
205 }
206
207 // Called when it's no longer safe to invoke |log_callback_|.
ShutdownLogging()208 void ShutdownLogging() { logging::SetLogMessageHandler(nullptr); }
209
210 private:
211 base::Lock message_lock_;
212 std::vector<LogMessage> deferred_messages_ GUARDED_BY(message_lock_);
213
214 // Set once under |mesage_lock_|, but may be accessed without lock after that.
215 LogCallback log_callback_;
216 };
217
GetLogMessageManager()218 LogMessageManager* GetLogMessageManager() {
219 static base::NoDestructor<LogMessageManager> message_manager;
220 return message_manager.get();
221 }
222
PreInitializeLogHandler(int severity,const char * file,int line,size_t message_start,const std::string & message)223 bool PreInitializeLogHandler(int severity,
224 const char* file,
225 int line,
226 size_t message_start,
227 const std::string& message) {
228 GetLogMessageManager()->AddDeferredMessage(severity,
229 message.substr(0, message_start),
230 message.substr(message_start));
231 return false;
232 }
233
PostInitializeLogHandler(int severity,const char * file,int line,size_t message_start,const std::string & message)234 bool PostInitializeLogHandler(int severity,
235 const char* file,
236 int line,
237 size_t message_start,
238 const std::string& message) {
239 GetLogMessageManager()->RouteMessage(severity,
240 message.substr(0, message_start),
241 message.substr(message_start));
242 return false;
243 }
244
IsAcceleratedJpegDecodeSupported()245 bool IsAcceleratedJpegDecodeSupported() {
246 #if defined(OS_CHROMEOS)
247 return chromeos_camera::GpuMjpegDecodeAcceleratorFactory::
248 IsAcceleratedJpegDecodeSupported();
249 #else
250 return false;
251 #endif // defined(OS_CHROMEOS)
252 }
253
GetVideoCapabilities(const gpu::GpuPreferences & gpu_preferences,const gpu::GpuDriverBugWorkarounds & gpu_workarounds,gpu::GPUInfo * gpu_info)254 void GetVideoCapabilities(const gpu::GpuPreferences& gpu_preferences,
255 const gpu::GpuDriverBugWorkarounds& gpu_workarounds,
256 gpu::GPUInfo* gpu_info) {
257 // Due to https://crbug.com/709631, we don't want to query Android video
258 // decode/encode capabilities during startup. The renderer needs this info
259 // though, so assume some baseline capabilities.
260 #if defined(OS_ANDROID)
261 // Note: Video encoding on Android relies on MediaCodec, so all cases
262 // where it's disabled for decoding it is also disabled for encoding.
263 if (gpu_preferences.disable_accelerated_video_decode ||
264 gpu_preferences.disable_accelerated_video_encode) {
265 return;
266 }
267
268 auto& encoding_profiles =
269 gpu_info->video_encode_accelerator_supported_profiles;
270
271 gpu::VideoEncodeAcceleratorSupportedProfile vea_profile;
272 vea_profile.max_resolution = gfx::Size(1280, 720);
273 vea_profile.max_framerate_numerator = 30;
274 vea_profile.max_framerate_denominator = 1;
275
276 if (media::MediaCodecUtil::IsVp8EncoderAvailable()) {
277 vea_profile.profile = gpu::VP8PROFILE_ANY;
278 encoding_profiles.push_back(vea_profile);
279 }
280
281 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
282 if (media::MediaCodecUtil::IsH264EncoderAvailable(/*use_codec_list*/ false)) {
283 vea_profile.profile = gpu::H264PROFILE_BASELINE;
284 encoding_profiles.push_back(vea_profile);
285 }
286 #endif
287
288 // Note: Since Android doesn't have to support PPAPI/Flash, we have not
289 // returned the decoder profiles here since https://crrev.com/665999.
290 #else
291 gpu_info->video_decode_accelerator_capabilities =
292 media::GpuVideoDecodeAccelerator::GetCapabilities(gpu_preferences,
293 gpu_workarounds);
294 gpu_info->video_encode_accelerator_supported_profiles =
295 media::GpuVideoAcceleratorUtil::ConvertMediaToGpuEncodeProfiles(
296 media::GpuVideoEncodeAcceleratorFactory::GetSupportedProfiles(
297 gpu_preferences, gpu_workarounds));
298 #endif
299 }
300
301 // Returns a callback which does a PostTask to run |callback| on the |runner|
302 // task runner.
303 template <typename... Params>
WrapCallback(scoped_refptr<base::SingleThreadTaskRunner> runner,base::OnceCallback<void (Params...)> callback)304 base::OnceCallback<void(Params&&...)> WrapCallback(
305 scoped_refptr<base::SingleThreadTaskRunner> runner,
306 base::OnceCallback<void(Params...)> callback) {
307 return base::BindOnce(
308 [](base::SingleThreadTaskRunner* runner,
309 base::OnceCallback<void(Params && ...)> callback, Params&&... params) {
310 runner->PostTask(FROM_HERE,
311 base::BindOnce(std::move(callback),
312 std::forward<Params>(params)...));
313 },
314 base::RetainedRef(std::move(runner)), std::move(callback));
315 }
316
317 } // namespace
318
GpuServiceImpl(const gpu::GPUInfo & gpu_info,std::unique_ptr<gpu::GpuWatchdogThread> watchdog_thread,scoped_refptr<base::SingleThreadTaskRunner> io_runner,const gpu::GpuFeatureInfo & gpu_feature_info,const gpu::GpuPreferences & gpu_preferences,const base::Optional<gpu::GPUInfo> & gpu_info_for_hardware_gpu,const base::Optional<gpu::GpuFeatureInfo> & gpu_feature_info_for_hardware_gpu,const gfx::GpuExtraInfo & gpu_extra_info,gpu::VulkanImplementation * vulkan_implementation,base::OnceCallback<void (base::Optional<ExitCode>)> exit_callback)319 GpuServiceImpl::GpuServiceImpl(
320 const gpu::GPUInfo& gpu_info,
321 std::unique_ptr<gpu::GpuWatchdogThread> watchdog_thread,
322 scoped_refptr<base::SingleThreadTaskRunner> io_runner,
323 const gpu::GpuFeatureInfo& gpu_feature_info,
324 const gpu::GpuPreferences& gpu_preferences,
325 const base::Optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu,
326 const base::Optional<gpu::GpuFeatureInfo>&
327 gpu_feature_info_for_hardware_gpu,
328 const gfx::GpuExtraInfo& gpu_extra_info,
329 gpu::VulkanImplementation* vulkan_implementation,
330 base::OnceCallback<void(base::Optional<ExitCode>)> exit_callback)
331 : main_runner_(base::ThreadTaskRunnerHandle::Get()),
332 io_runner_(std::move(io_runner)),
333 watchdog_thread_(std::move(watchdog_thread)),
334 gpu_preferences_(gpu_preferences),
335 gpu_info_(gpu_info),
336 gpu_feature_info_(gpu_feature_info),
337 gpu_info_for_hardware_gpu_(gpu_info_for_hardware_gpu),
338 gpu_feature_info_for_hardware_gpu_(gpu_feature_info_for_hardware_gpu),
339 gpu_extra_info_(gpu_extra_info),
340 #if BUILDFLAG(ENABLE_VULKAN)
341 vulkan_implementation_(vulkan_implementation),
342 #endif
343 exit_callback_(std::move(exit_callback)) {
344 DCHECK(!io_runner_->BelongsToCurrentThread());
345 DCHECK(exit_callback_);
346
347 #if defined(OS_CHROMEOS)
348 protected_buffer_manager_ = new arc::ProtectedBufferManager();
349 #endif // defined(OS_CHROMEOS)
350
351 GrContextOptions context_options =
352 GetDefaultGrContextOptions(gpu_preferences_.gr_context_type);
353 if (gpu_preferences_.force_max_texture_size) {
354 context_options.fMaxTextureSizeOverride =
355 gpu_preferences_.force_max_texture_size;
356 }
357
358 #if BUILDFLAG(ENABLE_VULKAN)
359 if (vulkan_implementation_) {
360 bool is_native_vulkan =
361 gpu_preferences_.use_vulkan == gpu::VulkanImplementationName::kNative ||
362 gpu_preferences_.use_vulkan ==
363 gpu::VulkanImplementationName::kForcedNative;
364 // With swiftshader the vendor_id is 0xffff. For some tests gpu_info is not
365 // initialized, so the vendor_id is 0.
366 bool is_native_gl =
367 gpu_info_.gpu.vendor_id != 0xffff && gpu_info_.gpu.vendor_id != 0;
368 // If GL is using a real GPU, the gpu_info will be passed in and vulkan will
369 // use the same GPU.
370 vulkan_context_provider_ = VulkanInProcessContextProvider::Create(
371 vulkan_implementation_, gpu_preferences_.vulkan_heap_memory_limit,
372 gpu_preferences_.vulkan_sync_cpu_memory_limit,
373 (is_native_vulkan && is_native_gl) ? &gpu_info : nullptr);
374 if (vulkan_context_provider_) {
375 // If Vulkan is supported, then OOP-R is supported.
376 gpu_info_.oop_rasterization_supported = true;
377 gpu_feature_info_.status_values[gpu::GPU_FEATURE_TYPE_OOP_RASTERIZATION] =
378 gpu::kGpuFeatureStatusEnabled;
379 } else {
380 DLOG(ERROR) << "Failed to create Vulkan context provider.";
381 }
382 }
383 #endif
384
385 #if BUILDFLAG(SKIA_USE_DAWN)
386 if (gpu_preferences_.gr_context_type == gpu::GrContextType::kDawn) {
387 dawn_context_provider_ = DawnContextProvider::Create();
388 if (dawn_context_provider_) {
389 gpu_info_.oop_rasterization_supported = true;
390 gpu_feature_info_.status_values[gpu::GPU_FEATURE_TYPE_OOP_RASTERIZATION] =
391 gpu::kGpuFeatureStatusEnabled;
392 } else {
393 DLOG(ERROR) << "Failed to create Dawn context provider.";
394 }
395 }
396 #endif
397
398 #if BUILDFLAG(USE_VAAPI_IMAGE_CODECS)
399 image_decode_accelerator_worker_ =
400 media::VaapiImageDecodeAcceleratorWorker::Create();
401 #endif // BUILDFLAG(USE_VAAPI_IMAGE_CODECS)
402
403 #if defined(OS_APPLE)
404 if (gpu_feature_info_.status_values[gpu::GPU_FEATURE_TYPE_METAL] ==
405 gpu::kGpuFeatureStatusEnabled) {
406 metal_context_provider_ = MetalContextProvider::Create(context_options);
407 }
408 #endif
409
410 #if defined(OS_WIN)
411 auto info_callback = base::BindRepeating(
412 &GpuServiceImpl::UpdateOverlayAndHDRInfo, weak_ptr_factory_.GetWeakPtr());
413 gl::DirectCompositionSurfaceWin::SetOverlayHDRGpuInfoUpdateCallback(
414 info_callback);
415 #endif
416
417 gpu_memory_buffer_factory_ =
418 gpu::GpuMemoryBufferFactory::CreateNativeType(vulkan_context_provider());
419
420 weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
421 }
422
~GpuServiceImpl()423 GpuServiceImpl::~GpuServiceImpl() {
424 DCHECK(main_runner_->BelongsToCurrentThread());
425
426 // Ensure we don't try to exit when already in the process of exiting.
427 is_exiting_.Set();
428
429 bind_task_tracker_.TryCancelAll();
430 GetLogMessageManager()->ShutdownLogging();
431
432 // Destroy the receiver on the IO thread.
433 {
434 base::WaitableEvent wait;
435 auto destroy_receiver_task = base::BindOnce(
436 [](mojo::Receiver<mojom::GpuService>* receiver,
437 base::WaitableEvent* wait) {
438 receiver->reset();
439 wait->Signal();
440 },
441 &receiver_, base::Unretained(&wait));
442 if (io_runner_->PostTask(FROM_HERE, std::move(destroy_receiver_task)))
443 wait.Wait();
444 }
445
446 if (watchdog_thread_)
447 watchdog_thread_->OnGpuProcessTearDown();
448
449 media_gpu_channel_manager_.reset();
450 gpu_channel_manager_.reset();
451
452 // Destroy |gpu_memory_buffer_factory_| on the IO thread since its weakptrs
453 // are checked there.
454 {
455 base::WaitableEvent wait;
456 auto destroy_gmb_factory = base::BindOnce(
457 [](std::unique_ptr<gpu::GpuMemoryBufferFactory> gmb_factory,
458 base::WaitableEvent* wait) {
459 gmb_factory.reset();
460 wait->Signal();
461 },
462 std::move(gpu_memory_buffer_factory_), base::Unretained(&wait));
463
464 if (io_runner_->PostTask(FROM_HERE, std::move(destroy_gmb_factory))) {
465 // |gpu_memory_buffer_factory_| holds a raw pointer to
466 // |vulkan_context_provider_|. Waiting here enforces the correct order
467 // of destruction.
468 wait.Wait();
469 }
470 }
471
472 // Scheduler must be destroyed before sync point manager is destroyed.
473 scheduler_.reset();
474 owned_sync_point_manager_.reset();
475 owned_shared_image_manager_.reset();
476
477 // The image decode accelerator worker must outlive the GPU channel manager so
478 // that it doesn't get any decode requests during/after destruction.
479 DCHECK(!gpu_channel_manager_);
480 image_decode_accelerator_worker_.reset();
481
482 // Signal this event before destroying the child process. That way all
483 // background threads can cleanup. For example, in the renderer the
484 // RenderThread instances will be able to notice shutdown before the render
485 // process begins waiting for them to exit.
486 if (owned_shutdown_event_)
487 owned_shutdown_event_->Signal();
488 }
489
UpdateGPUInfo()490 void GpuServiceImpl::UpdateGPUInfo() {
491 DCHECK(main_runner_->BelongsToCurrentThread());
492 DCHECK(!gpu_host_);
493 gpu::GpuDriverBugWorkarounds gpu_workarounds(
494 gpu_feature_info_.enabled_gpu_driver_bug_workarounds);
495
496 GetVideoCapabilities(gpu_preferences_, gpu_workarounds, &gpu_info_);
497
498 gpu_info_.jpeg_decode_accelerator_supported =
499 IsAcceleratedJpegDecodeSupported();
500
501 if (image_decode_accelerator_worker_) {
502 gpu_info_.image_decode_accelerator_supported_profiles =
503 image_decode_accelerator_worker_->GetSupportedProfiles();
504 }
505
506 // Record initialization only after collecting the GPU info because that can
507 // take a significant amount of time.
508 gpu_info_.initialization_time = base::Time::Now() - start_time_;
509 }
510
InitializeWithHost(mojo::PendingRemote<mojom::GpuHost> pending_gpu_host,gpu::GpuProcessActivityFlags activity_flags,scoped_refptr<gl::GLSurface> default_offscreen_surface,gpu::SyncPointManager * sync_point_manager,gpu::SharedImageManager * shared_image_manager,base::WaitableEvent * shutdown_event)511 void GpuServiceImpl::InitializeWithHost(
512 mojo::PendingRemote<mojom::GpuHost> pending_gpu_host,
513 gpu::GpuProcessActivityFlags activity_flags,
514 scoped_refptr<gl::GLSurface> default_offscreen_surface,
515 gpu::SyncPointManager* sync_point_manager,
516 gpu::SharedImageManager* shared_image_manager,
517 base::WaitableEvent* shutdown_event) {
518 DCHECK(main_runner_->BelongsToCurrentThread());
519
520 mojo::Remote<mojom::GpuHost> gpu_host(std::move(pending_gpu_host));
521 gpu_host->DidInitialize(gpu_info_, gpu_feature_info_,
522 gpu_info_for_hardware_gpu_,
523 gpu_feature_info_for_hardware_gpu_, gpu_extra_info_);
524 gpu_host_ = mojo::SharedRemote<mojom::GpuHost>(gpu_host.Unbind(), io_runner_);
525 if (!in_host_process()) {
526 // The global callback is reset from the dtor. So Unretained() here is safe.
527 // Note that the callback can be called from any thread. Consequently, the
528 // callback cannot use a WeakPtr.
529 GetLogMessageManager()->InstallPostInitializeLogHandler(base::BindRepeating(
530 &GpuServiceImpl::RecordLogMessage, base::Unretained(this)));
531 }
532
533 if (!sync_point_manager) {
534 owned_sync_point_manager_ = std::make_unique<gpu::SyncPointManager>();
535 sync_point_manager = owned_sync_point_manager_.get();
536 }
537
538 if (!shared_image_manager) {
539 // When using real buffers for testing overlay configurations, we need
540 // access to SharedImageManager on the viz thread to obtain the buffer
541 // corresponding to a mailbox.
542 bool thread_safe_manager = features::ShouldUseRealBuffersForPageFlipTest();
543 owned_shared_image_manager_ = std::make_unique<gpu::SharedImageManager>(
544 thread_safe_manager, false /* display_context_on_another_thread */);
545 shared_image_manager = owned_shared_image_manager_.get();
546 } else {
547 // With this feature enabled, we don't expect to receive an external
548 // SharedImageManager.
549 DCHECK(!features::ShouldUseRealBuffersForPageFlipTest());
550 }
551
552 shutdown_event_ = shutdown_event;
553 if (!shutdown_event_) {
554 owned_shutdown_event_ = std::make_unique<base::WaitableEvent>(
555 base::WaitableEvent::ResetPolicy::MANUAL,
556 base::WaitableEvent::InitialState::NOT_SIGNALED);
557 shutdown_event_ = owned_shutdown_event_.get();
558 }
559
560 scheduler_ = std::make_unique<gpu::Scheduler>(
561 main_runner_, sync_point_manager, gpu_preferences_);
562
563 // Defer creation of the render thread. This is to prevent it from handling
564 // IPC messages before the sandbox has been enabled and all other necessary
565 // initialization has succeeded.
566 gpu_channel_manager_ = std::make_unique<gpu::GpuChannelManager>(
567 gpu_preferences_, this, watchdog_thread_.get(), main_runner_, io_runner_,
568 scheduler_.get(), sync_point_manager, shared_image_manager,
569 gpu_memory_buffer_factory_.get(), gpu_feature_info_,
570 std::move(activity_flags), std::move(default_offscreen_surface),
571 image_decode_accelerator_worker_.get(), vulkan_context_provider(),
572 metal_context_provider_.get(), dawn_context_provider());
573
574 media_gpu_channel_manager_.reset(
575 new media::MediaGpuChannelManager(gpu_channel_manager_.get()));
576 if (watchdog_thread())
577 watchdog_thread()->AddPowerObserver();
578 }
579
Bind(mojo::PendingReceiver<mojom::GpuService> pending_receiver)580 void GpuServiceImpl::Bind(
581 mojo::PendingReceiver<mojom::GpuService> pending_receiver) {
582 if (main_runner_->BelongsToCurrentThread()) {
583 bind_task_tracker_.PostTask(
584 io_runner_.get(), FROM_HERE,
585 base::BindOnce(&GpuServiceImpl::Bind, base::Unretained(this),
586 std::move(pending_receiver)));
587 return;
588 }
589 DCHECK(!receiver_.is_bound());
590 receiver_.Bind(std::move(pending_receiver));
591 }
592
DisableGpuCompositing()593 void GpuServiceImpl::DisableGpuCompositing() {
594 // Can be called from any thread.
595 gpu_host_->DisableGpuCompositing();
596 }
597
GetContextState()598 scoped_refptr<gpu::SharedContextState> GpuServiceImpl::GetContextState() {
599 DCHECK(main_runner_->BelongsToCurrentThread());
600 gpu::ContextResult result;
601 return gpu_channel_manager_->GetSharedContextState(&result);
602 }
603
gpu_image_factory()604 gpu::ImageFactory* GpuServiceImpl::gpu_image_factory() {
605 return gpu_memory_buffer_factory_
606 ? gpu_memory_buffer_factory_->AsImageFactory()
607 : nullptr;
608 }
609
610 // static
InstallPreInitializeLogHandler()611 void GpuServiceImpl::InstallPreInitializeLogHandler() {
612 GetLogMessageManager()->InstallPreInitializeLogHandler();
613 }
614
615 // static
FlushPreInitializeLogMessages(mojom::GpuHost * gpu_host)616 void GpuServiceImpl::FlushPreInitializeLogMessages(mojom::GpuHost* gpu_host) {
617 GetLogMessageManager()->FlushMessages(gpu_host);
618 }
619
RecordLogMessage(int severity,const std::string & header,const std::string & message)620 void GpuServiceImpl::RecordLogMessage(int severity,
621 const std::string& header,
622 const std::string& message) {
623 // This can be run from any thread.
624 gpu_host_->RecordLogMessage(severity, std::move(header), std::move(message));
625 }
626
627 #if defined(OS_CHROMEOS)
CreateArcVideoDecodeAccelerator(mojo::PendingReceiver<arc::mojom::VideoDecodeAccelerator> vda_receiver)628 void GpuServiceImpl::CreateArcVideoDecodeAccelerator(
629 mojo::PendingReceiver<arc::mojom::VideoDecodeAccelerator> vda_receiver) {
630 DCHECK(io_runner_->BelongsToCurrentThread());
631 main_runner_->PostTask(
632 FROM_HERE,
633 base::BindOnce(
634 &GpuServiceImpl::CreateArcVideoDecodeAcceleratorOnMainThread,
635 weak_ptr_, std::move(vda_receiver)));
636 }
637
CreateArcVideoEncodeAccelerator(mojo::PendingReceiver<arc::mojom::VideoEncodeAccelerator> vea_receiver)638 void GpuServiceImpl::CreateArcVideoEncodeAccelerator(
639 mojo::PendingReceiver<arc::mojom::VideoEncodeAccelerator> vea_receiver) {
640 DCHECK(io_runner_->BelongsToCurrentThread());
641 main_runner_->PostTask(
642 FROM_HERE,
643 base::BindOnce(
644 &GpuServiceImpl::CreateArcVideoEncodeAcceleratorOnMainThread,
645 weak_ptr_, std::move(vea_receiver)));
646 }
647
CreateArcVideoProtectedBufferAllocator(mojo::PendingReceiver<arc::mojom::VideoProtectedBufferAllocator> pba_receiver)648 void GpuServiceImpl::CreateArcVideoProtectedBufferAllocator(
649 mojo::PendingReceiver<arc::mojom::VideoProtectedBufferAllocator>
650 pba_receiver) {
651 DCHECK(io_runner_->BelongsToCurrentThread());
652 main_runner_->PostTask(
653 FROM_HERE,
654 base::BindOnce(
655 &GpuServiceImpl::CreateArcVideoProtectedBufferAllocatorOnMainThread,
656 weak_ptr_, std::move(pba_receiver)));
657 }
658
CreateArcProtectedBufferManager(mojo::PendingReceiver<arc::mojom::ProtectedBufferManager> pbm_receiver)659 void GpuServiceImpl::CreateArcProtectedBufferManager(
660 mojo::PendingReceiver<arc::mojom::ProtectedBufferManager> pbm_receiver) {
661 DCHECK(io_runner_->BelongsToCurrentThread());
662 main_runner_->PostTask(
663 FROM_HERE,
664 base::BindOnce(
665 &GpuServiceImpl::CreateArcProtectedBufferManagerOnMainThread,
666 weak_ptr_, std::move(pbm_receiver)));
667 }
668
CreateArcVideoDecodeAcceleratorOnMainThread(mojo::PendingReceiver<arc::mojom::VideoDecodeAccelerator> vda_receiver)669 void GpuServiceImpl::CreateArcVideoDecodeAcceleratorOnMainThread(
670 mojo::PendingReceiver<arc::mojom::VideoDecodeAccelerator> vda_receiver) {
671 DCHECK(main_runner_->BelongsToCurrentThread());
672 mojo::MakeSelfOwnedReceiver(
673 std::make_unique<arc::GpuArcVideoDecodeAccelerator>(
674 gpu_preferences_, gpu_channel_manager_->gpu_driver_bug_workarounds(),
675 protected_buffer_manager_),
676 std::move(vda_receiver));
677 }
678
CreateArcVideoEncodeAcceleratorOnMainThread(mojo::PendingReceiver<arc::mojom::VideoEncodeAccelerator> vea_receiver)679 void GpuServiceImpl::CreateArcVideoEncodeAcceleratorOnMainThread(
680 mojo::PendingReceiver<arc::mojom::VideoEncodeAccelerator> vea_receiver) {
681 DCHECK(main_runner_->BelongsToCurrentThread());
682 mojo::MakeSelfOwnedReceiver(
683 std::make_unique<arc::GpuArcVideoEncodeAccelerator>(
684 gpu_preferences_, gpu_channel_manager_->gpu_driver_bug_workarounds()),
685 std::move(vea_receiver));
686 }
687
CreateArcVideoProtectedBufferAllocatorOnMainThread(mojo::PendingReceiver<arc::mojom::VideoProtectedBufferAllocator> pba_receiver)688 void GpuServiceImpl::CreateArcVideoProtectedBufferAllocatorOnMainThread(
689 mojo::PendingReceiver<arc::mojom::VideoProtectedBufferAllocator>
690 pba_receiver) {
691 DCHECK(main_runner_->BelongsToCurrentThread());
692 auto gpu_arc_video_protected_buffer_allocator =
693 arc::GpuArcVideoProtectedBufferAllocator::Create(
694 protected_buffer_manager_);
695 if (!gpu_arc_video_protected_buffer_allocator)
696 return;
697 mojo::MakeSelfOwnedReceiver(
698 std::move(gpu_arc_video_protected_buffer_allocator),
699 std::move(pba_receiver));
700 }
701
CreateArcProtectedBufferManagerOnMainThread(mojo::PendingReceiver<arc::mojom::ProtectedBufferManager> pbm_receiver)702 void GpuServiceImpl::CreateArcProtectedBufferManagerOnMainThread(
703 mojo::PendingReceiver<arc::mojom::ProtectedBufferManager> pbm_receiver) {
704 DCHECK(main_runner_->BelongsToCurrentThread());
705 mojo::MakeSelfOwnedReceiver(
706 std::make_unique<arc::GpuArcProtectedBufferManagerProxy>(
707 protected_buffer_manager_),
708 std::move(pbm_receiver));
709 }
710
CreateJpegDecodeAccelerator(mojo::PendingReceiver<chromeos_camera::mojom::MjpegDecodeAccelerator> jda_receiver)711 void GpuServiceImpl::CreateJpegDecodeAccelerator(
712 mojo::PendingReceiver<chromeos_camera::mojom::MjpegDecodeAccelerator>
713 jda_receiver) {
714 DCHECK(io_runner_->BelongsToCurrentThread());
715 chromeos_camera::MojoMjpegDecodeAcceleratorService::Create(
716 std::move(jda_receiver));
717 }
718
CreateJpegEncodeAccelerator(mojo::PendingReceiver<chromeos_camera::mojom::JpegEncodeAccelerator> jea_receiver)719 void GpuServiceImpl::CreateJpegEncodeAccelerator(
720 mojo::PendingReceiver<chromeos_camera::mojom::JpegEncodeAccelerator>
721 jea_receiver) {
722 DCHECK(io_runner_->BelongsToCurrentThread());
723 chromeos_camera::MojoJpegEncodeAcceleratorService::Create(
724 std::move(jea_receiver));
725 }
726 #endif // defined(OS_CHROMEOS)
727
CreateVideoEncodeAcceleratorProvider(mojo::PendingReceiver<media::mojom::VideoEncodeAcceleratorProvider> vea_provider_receiver)728 void GpuServiceImpl::CreateVideoEncodeAcceleratorProvider(
729 mojo::PendingReceiver<media::mojom::VideoEncodeAcceleratorProvider>
730 vea_provider_receiver) {
731 DCHECK(io_runner_->BelongsToCurrentThread());
732 media::MojoVideoEncodeAcceleratorProvider::Create(
733 std::move(vea_provider_receiver),
734 base::BindRepeating(&media::GpuVideoEncodeAcceleratorFactory::CreateVEA),
735 gpu_preferences_, gpu_channel_manager_->gpu_driver_bug_workarounds());
736 }
737
CreateGpuMemoryBuffer(gfx::GpuMemoryBufferId id,const gfx::Size & size,gfx::BufferFormat format,gfx::BufferUsage usage,int client_id,gpu::SurfaceHandle surface_handle,CreateGpuMemoryBufferCallback callback)738 void GpuServiceImpl::CreateGpuMemoryBuffer(
739 gfx::GpuMemoryBufferId id,
740 const gfx::Size& size,
741 gfx::BufferFormat format,
742 gfx::BufferUsage usage,
743 int client_id,
744 gpu::SurfaceHandle surface_handle,
745 CreateGpuMemoryBufferCallback callback) {
746 DCHECK(io_runner_->BelongsToCurrentThread());
747 // This needs to happen in the IO thread.
748 gpu_memory_buffer_factory_->CreateGpuMemoryBufferAsync(
749 id, size, format, usage, client_id, surface_handle, std::move(callback));
750 }
751
DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,int client_id,const gpu::SyncToken & sync_token)752 void GpuServiceImpl::DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
753 int client_id,
754 const gpu::SyncToken& sync_token) {
755 if (io_runner_->BelongsToCurrentThread()) {
756 main_runner_->PostTask(
757 FROM_HERE, base::BindOnce(&GpuServiceImpl::DestroyGpuMemoryBuffer,
758 weak_ptr_, id, client_id, sync_token));
759 return;
760 }
761 gpu_channel_manager_->DestroyGpuMemoryBuffer(id, client_id, sync_token);
762 }
763
GetVideoMemoryUsageStats(GetVideoMemoryUsageStatsCallback callback)764 void GpuServiceImpl::GetVideoMemoryUsageStats(
765 GetVideoMemoryUsageStatsCallback callback) {
766 if (io_runner_->BelongsToCurrentThread()) {
767 auto wrap_callback = WrapCallback(io_runner_, std::move(callback));
768 main_runner_->PostTask(
769 FROM_HERE, base::BindOnce(&GpuServiceImpl::GetVideoMemoryUsageStats,
770 weak_ptr_, std::move(wrap_callback)));
771 return;
772 }
773 gpu::VideoMemoryUsageStats video_memory_usage_stats;
774 gpu_channel_manager_->GetVideoMemoryUsageStats(&video_memory_usage_stats);
775 std::move(callback).Run(video_memory_usage_stats);
776 }
777
StartPeakMemoryMonitor(uint32_t sequence_num)778 void GpuServiceImpl::StartPeakMemoryMonitor(uint32_t sequence_num) {
779 DCHECK(io_runner_->BelongsToCurrentThread());
780 main_runner_->PostTask(
781 FROM_HERE,
782 base::BindOnce(&GpuServiceImpl::StartPeakMemoryMonitorOnMainThread,
783 weak_ptr_, sequence_num));
784 }
785
GetPeakMemoryUsage(uint32_t sequence_num,GetPeakMemoryUsageCallback callback)786 void GpuServiceImpl::GetPeakMemoryUsage(uint32_t sequence_num,
787 GetPeakMemoryUsageCallback callback) {
788 DCHECK(io_runner_->BelongsToCurrentThread());
789 main_runner_->PostTask(
790 FROM_HERE, base::BindOnce(&GpuServiceImpl::GetPeakMemoryUsageOnMainThread,
791 weak_ptr_, sequence_num, std::move(callback)));
792 }
793
RequestHDRStatus(RequestHDRStatusCallback callback)794 void GpuServiceImpl::RequestHDRStatus(RequestHDRStatusCallback callback) {
795 DCHECK(io_runner_->BelongsToCurrentThread());
796 main_runner_->PostTask(
797 FROM_HERE, base::BindOnce(&GpuServiceImpl::RequestHDRStatusOnMainThread,
798 weak_ptr_, std::move(callback)));
799 }
800
RequestHDRStatusOnMainThread(RequestHDRStatusCallback callback)801 void GpuServiceImpl::RequestHDRStatusOnMainThread(
802 RequestHDRStatusCallback callback) {
803 DCHECK(main_runner_->BelongsToCurrentThread());
804
805 #if defined(OS_WIN)
806 hdr_enabled_ = gl::DirectCompositionSurfaceWin::IsHDRSupported();
807 #endif
808 io_runner_->PostTask(FROM_HERE,
809 base::BindOnce(std::move(callback), hdr_enabled_));
810 }
811
RegisterDisplayContext(gpu::DisplayContext * display_context)812 void GpuServiceImpl::RegisterDisplayContext(
813 gpu::DisplayContext* display_context) {
814 DCHECK(main_runner_->BelongsToCurrentThread());
815 display_contexts_.AddObserver(display_context);
816 }
817
UnregisterDisplayContext(gpu::DisplayContext * display_context)818 void GpuServiceImpl::UnregisterDisplayContext(
819 gpu::DisplayContext* display_context) {
820 DCHECK(main_runner_->BelongsToCurrentThread());
821 display_contexts_.RemoveObserver(display_context);
822 }
823
LoseAllContexts()824 void GpuServiceImpl::LoseAllContexts() {
825 DCHECK(main_runner_->BelongsToCurrentThread());
826
827 if (IsExiting())
828 return;
829
830 for (auto& display_context : display_contexts_)
831 display_context.MarkContextLost();
832 gpu_channel_manager_->LoseAllContexts();
833 }
834
DidCreateContextSuccessfully()835 void GpuServiceImpl::DidCreateContextSuccessfully() {
836 DCHECK(main_runner_->BelongsToCurrentThread());
837 gpu_host_->DidCreateContextSuccessfully();
838 }
839
DidCreateOffscreenContext(const GURL & active_url)840 void GpuServiceImpl::DidCreateOffscreenContext(const GURL& active_url) {
841 DCHECK(main_runner_->BelongsToCurrentThread());
842 gpu_host_->DidCreateOffscreenContext(active_url);
843 }
844
DidDestroyChannel(int client_id)845 void GpuServiceImpl::DidDestroyChannel(int client_id) {
846 DCHECK(main_runner_->BelongsToCurrentThread());
847 media_gpu_channel_manager_->RemoveChannel(client_id);
848 gpu_host_->DidDestroyChannel(client_id);
849 }
850
DidDestroyAllChannels()851 void GpuServiceImpl::DidDestroyAllChannels() {
852 DCHECK(main_runner_->BelongsToCurrentThread());
853 gpu_host_->DidDestroyAllChannels();
854 }
855
DidDestroyOffscreenContext(const GURL & active_url)856 void GpuServiceImpl::DidDestroyOffscreenContext(const GURL& active_url) {
857 DCHECK(main_runner_->BelongsToCurrentThread());
858 gpu_host_->DidDestroyOffscreenContext(active_url);
859 }
860
DidLoseContext(bool offscreen,gpu::error::ContextLostReason reason,const GURL & active_url)861 void GpuServiceImpl::DidLoseContext(bool offscreen,
862 gpu::error::ContextLostReason reason,
863 const GURL& active_url) {
864 DCHECK(main_runner_->BelongsToCurrentThread());
865 gpu_host_->DidLoseContext(offscreen, reason, active_url);
866 }
867
868 #if defined(OS_WIN)
DidUpdateOverlayInfo(const gpu::OverlayInfo & overlay_info)869 void GpuServiceImpl::DidUpdateOverlayInfo(
870 const gpu::OverlayInfo& overlay_info) {
871 gpu_host_->DidUpdateOverlayInfo(gpu_info_.overlay_info);
872 }
873
DidUpdateHDRStatus(bool hdr_enabled)874 void GpuServiceImpl::DidUpdateHDRStatus(bool hdr_enabled) {
875 gpu_host_->DidUpdateHDRStatus(hdr_enabled);
876 }
877 #endif
878
StoreShaderToDisk(int client_id,const std::string & key,const std::string & shader)879 void GpuServiceImpl::StoreShaderToDisk(int client_id,
880 const std::string& key,
881 const std::string& shader) {
882 DCHECK(main_runner_->BelongsToCurrentThread());
883 gpu_host_->StoreShaderToDisk(client_id, key, shader);
884 }
885
MaybeExitOnContextLost()886 void GpuServiceImpl::MaybeExitOnContextLost() {
887 MaybeExit(true);
888 }
889
IsExiting() const890 bool GpuServiceImpl::IsExiting() const {
891 return is_exiting_.IsSet();
892 }
893
894 #if defined(OS_WIN)
SendCreatedChildWindow(gpu::SurfaceHandle parent_window,gpu::SurfaceHandle child_window)895 void GpuServiceImpl::SendCreatedChildWindow(gpu::SurfaceHandle parent_window,
896 gpu::SurfaceHandle child_window) {
897 // This can be called from main or display compositor thread.
898 gpu_host_->SetChildSurface(parent_window, child_window);
899 }
900 #endif
901
EstablishGpuChannel(int32_t client_id,uint64_t client_tracing_id,bool is_gpu_host,bool cache_shaders_on_disk,EstablishGpuChannelCallback callback)902 void GpuServiceImpl::EstablishGpuChannel(int32_t client_id,
903 uint64_t client_tracing_id,
904 bool is_gpu_host,
905 bool cache_shaders_on_disk,
906 EstablishGpuChannelCallback callback) {
907 // This should always be called on the IO thread first.
908 if (io_runner_->BelongsToCurrentThread()) {
909 if (IsExiting()) {
910 // We are already exiting so there is no point in responding. Close the
911 // receiver so we can safely drop the callback.
912 receiver_.reset();
913 return;
914 }
915
916 if (gpu::IsReservedClientId(client_id)) {
917 // This returns a null handle, which is treated by the client as a failure
918 // case.
919 std::move(callback).Run(mojo::ScopedMessagePipeHandle());
920 return;
921 }
922
923 EstablishGpuChannelCallback wrap_callback = base::BindOnce(
924 [](scoped_refptr<base::SingleThreadTaskRunner> runner,
925 EstablishGpuChannelCallback cb,
926 mojo::ScopedMessagePipeHandle handle) {
927 runner->PostTask(FROM_HERE,
928 base::BindOnce(std::move(cb), std::move(handle)));
929 },
930 io_runner_, std::move(callback));
931 main_runner_->PostTask(
932 FROM_HERE,
933 base::BindOnce(&GpuServiceImpl::EstablishGpuChannel, weak_ptr_,
934 client_id, client_tracing_id, is_gpu_host,
935 cache_shaders_on_disk, std::move(wrap_callback)));
936 return;
937 }
938
939 gpu::GpuChannel* gpu_channel = gpu_channel_manager_->EstablishChannel(
940 client_id, client_tracing_id, is_gpu_host, cache_shaders_on_disk);
941
942 if (!gpu_channel) {
943 // This returns a null handle, which is treated by the client as a failure
944 // case.
945 std::move(callback).Run(mojo::ScopedMessagePipeHandle());
946 return;
947 }
948 mojo::MessagePipe pipe;
949 gpu_channel->Init(pipe.handle0.release(), shutdown_event_);
950
951 media_gpu_channel_manager_->AddChannel(client_id);
952
953 std::move(callback).Run(std::move(pipe.handle1));
954 }
955
CloseChannel(int32_t client_id)956 void GpuServiceImpl::CloseChannel(int32_t client_id) {
957 if (io_runner_->BelongsToCurrentThread()) {
958 main_runner_->PostTask(
959 FROM_HERE,
960 base::BindOnce(&GpuServiceImpl::CloseChannel, weak_ptr_, client_id));
961 return;
962 }
963 gpu_channel_manager_->RemoveChannel(client_id);
964 }
965
LoadedShader(int32_t client_id,const std::string & key,const std::string & data)966 void GpuServiceImpl::LoadedShader(int32_t client_id,
967 const std::string& key,
968 const std::string& data) {
969 if (io_runner_->BelongsToCurrentThread()) {
970 main_runner_->PostTask(
971 FROM_HERE, base::BindOnce(&GpuServiceImpl::LoadedShader, weak_ptr_,
972 client_id, key, data));
973 return;
974 }
975 gpu_channel_manager_->PopulateShaderCache(client_id, key, data);
976 }
977
WakeUpGpu()978 void GpuServiceImpl::WakeUpGpu() {
979 if (io_runner_->BelongsToCurrentThread()) {
980 main_runner_->PostTask(
981 FROM_HERE, base::BindOnce(&GpuServiceImpl::WakeUpGpu, weak_ptr_));
982 return;
983 }
984 #if defined(OS_ANDROID)
985 gpu_channel_manager_->WakeUpGpu();
986 #else
987 NOTREACHED() << "WakeUpGpu() not supported on this platform.";
988 #endif
989 }
990
GpuSwitched(gl::GpuPreference active_gpu_heuristic)991 void GpuServiceImpl::GpuSwitched(gl::GpuPreference active_gpu_heuristic) {
992 DVLOG(1) << "GPU: GPU has switched";
993 if (!in_host_process())
994 ui::GpuSwitchingManager::GetInstance()->NotifyGpuSwitched(
995 active_gpu_heuristic);
996 }
997
DisplayAdded()998 void GpuServiceImpl::DisplayAdded() {
999 if (io_runner_->BelongsToCurrentThread()) {
1000 main_runner_->PostTask(
1001 FROM_HERE, base::BindOnce(&GpuServiceImpl::DisplayAdded, weak_ptr_));
1002 return;
1003 }
1004 DVLOG(1) << "GPU: A monitor is plugged in";
1005
1006 if (!in_host_process())
1007 ui::GpuSwitchingManager::GetInstance()->NotifyDisplayAdded();
1008 }
1009
DisplayRemoved()1010 void GpuServiceImpl::DisplayRemoved() {
1011 if (io_runner_->BelongsToCurrentThread()) {
1012 main_runner_->PostTask(
1013 FROM_HERE, base::BindOnce(&GpuServiceImpl::DisplayRemoved, weak_ptr_));
1014 return;
1015 }
1016 DVLOG(1) << "GPU: A monitor is unplugged ";
1017
1018 if (!in_host_process())
1019 ui::GpuSwitchingManager::GetInstance()->NotifyDisplayRemoved();
1020 }
1021
DisplayMetricsChanged()1022 void GpuServiceImpl::DisplayMetricsChanged() {
1023 if (io_runner_->BelongsToCurrentThread()) {
1024 main_runner_->PostTask(
1025 FROM_HERE,
1026 base::BindOnce(&GpuServiceImpl::DisplayMetricsChanged, weak_ptr_));
1027 return;
1028 }
1029 DVLOG(1) << "GPU: Display Metrics changed";
1030
1031 if (!in_host_process())
1032 ui::GpuSwitchingManager::GetInstance()->NotifyDisplayMetricsChanged();
1033 }
1034
DestroyAllChannels()1035 void GpuServiceImpl::DestroyAllChannels() {
1036 if (io_runner_->BelongsToCurrentThread()) {
1037 main_runner_->PostTask(
1038 FROM_HERE,
1039 base::BindOnce(&GpuServiceImpl::DestroyAllChannels, weak_ptr_));
1040 return;
1041 }
1042 DVLOG(1) << "GPU: Removing all contexts";
1043 gpu_channel_manager_->DestroyAllChannels();
1044 }
1045
OnBackgroundCleanup()1046 void GpuServiceImpl::OnBackgroundCleanup() {
1047 // Currently only called on Android.
1048 #if defined(OS_ANDROID)
1049 if (io_runner_->BelongsToCurrentThread()) {
1050 main_runner_->PostTask(
1051 FROM_HERE,
1052 base::BindOnce(&GpuServiceImpl::OnBackgroundCleanup, weak_ptr_));
1053 return;
1054 }
1055 DVLOG(1) << "GPU: Performing background cleanup";
1056 gpu_channel_manager_->OnBackgroundCleanup();
1057 #else
1058 NOTREACHED();
1059 #endif
1060 }
1061
OnBackgrounded()1062 void GpuServiceImpl::OnBackgrounded() {
1063 DCHECK(io_runner_->BelongsToCurrentThread());
1064 if (watchdog_thread_)
1065 watchdog_thread_->OnBackgrounded();
1066
1067 main_runner_->PostTask(
1068 FROM_HERE,
1069 base::BindOnce(&GpuServiceImpl::OnBackgroundedOnMainThread, weak_ptr_));
1070 }
1071
OnBackgroundedOnMainThread()1072 void GpuServiceImpl::OnBackgroundedOnMainThread() {
1073 gpu_channel_manager_->OnApplicationBackgrounded();
1074 }
1075
OnForegrounded()1076 void GpuServiceImpl::OnForegrounded() {
1077 if (watchdog_thread_)
1078 watchdog_thread_->OnForegrounded();
1079 }
1080
1081 #if !defined(OS_ANDROID)
OnMemoryPressure(::base::MemoryPressureListener::MemoryPressureLevel level)1082 void GpuServiceImpl::OnMemoryPressure(
1083 ::base::MemoryPressureListener::MemoryPressureLevel level) {
1084 // Forward the notification to the registry of MemoryPressureListeners.
1085 base::MemoryPressureListener::NotifyMemoryPressure(level);
1086 }
1087 #endif
1088
1089 #if defined(OS_APPLE)
BeginCATransaction()1090 void GpuServiceImpl::BeginCATransaction() {
1091 DCHECK(io_runner_->BelongsToCurrentThread());
1092 main_runner_->PostTask(FROM_HERE, base::BindOnce(&ui::BeginCATransaction));
1093 }
1094
CommitCATransaction(CommitCATransactionCallback callback)1095 void GpuServiceImpl::CommitCATransaction(CommitCATransactionCallback callback) {
1096 DCHECK(io_runner_->BelongsToCurrentThread());
1097 main_runner_->PostTaskAndReply(FROM_HERE,
1098 base::BindOnce(&ui::CommitCATransaction),
1099 WrapCallback(io_runner_, std::move(callback)));
1100 }
1101 #endif
1102
1103 #if BUILDFLAG(CLANG_PROFILING_INSIDE_SANDBOX)
WriteClangProfilingProfile(WriteClangProfilingProfileCallback callback)1104 void GpuServiceImpl::WriteClangProfilingProfile(
1105 WriteClangProfilingProfileCallback callback) {
1106 base::WriteClangProfilingProfile();
1107 std::move(callback).Run();
1108 }
1109 #endif
1110
Crash()1111 void GpuServiceImpl::Crash() {
1112 DCHECK(io_runner_->BelongsToCurrentThread());
1113 gl::Crash();
1114 }
1115
Hang()1116 void GpuServiceImpl::Hang() {
1117 DCHECK(io_runner_->BelongsToCurrentThread());
1118 main_runner_->PostTask(FROM_HERE, base::BindOnce(&gl::Hang));
1119 }
1120
ThrowJavaException()1121 void GpuServiceImpl::ThrowJavaException() {
1122 DCHECK(io_runner_->BelongsToCurrentThread());
1123 #if defined(OS_ANDROID)
1124 ThrowUncaughtException();
1125 #else
1126 NOTREACHED() << "Java exception not supported on this platform.";
1127 #endif
1128 }
1129
Stop(StopCallback callback)1130 void GpuServiceImpl::Stop(StopCallback callback) {
1131 DCHECK(io_runner_->BelongsToCurrentThread());
1132 main_runner_->PostTaskAndReply(
1133 FROM_HERE, base::BindOnce(&GpuServiceImpl::MaybeExit, weak_ptr_, false),
1134 std::move(callback));
1135 }
1136
StartPeakMemoryMonitorOnMainThread(uint32_t sequence_num)1137 void GpuServiceImpl::StartPeakMemoryMonitorOnMainThread(uint32_t sequence_num) {
1138 gpu_channel_manager_->StartPeakMemoryMonitor(sequence_num);
1139 }
1140
GetPeakMemoryUsageOnMainThread(uint32_t sequence_num,GetPeakMemoryUsageCallback callback)1141 void GpuServiceImpl::GetPeakMemoryUsageOnMainThread(
1142 uint32_t sequence_num,
1143 GetPeakMemoryUsageCallback callback) {
1144 uint64_t peak_memory = 0u;
1145 auto allocation_per_source =
1146 gpu_channel_manager_->GetPeakMemoryUsage(sequence_num, &peak_memory);
1147 io_runner_->PostTask(FROM_HERE,
1148 base::BindOnce(std::move(callback), peak_memory,
1149 std::move(allocation_per_source)));
1150 }
1151
MaybeExit(bool for_context_loss)1152 void GpuServiceImpl::MaybeExit(bool for_context_loss) {
1153 DCHECK(main_runner_->BelongsToCurrentThread());
1154
1155 // We can't restart the GPU process when running in the host process.
1156 if (in_host_process())
1157 return;
1158
1159 if (IsExiting() || !exit_callback_)
1160 return;
1161
1162 if (for_context_loss) {
1163 LOG(ERROR) << "Exiting GPU process because some drivers can't recover "
1164 "from errors. GPU process will restart shortly.";
1165 }
1166 is_exiting_.Set();
1167 // For the unsandboxed GPU info collection process used for info collection,
1168 // if we exit immediately, then the reply message could be lost. That's why
1169 // the |exit_callback_| takes the boolean argument.
1170 if (for_context_loss)
1171 std::move(exit_callback_)
1172 .Run(ExitCode::RESULT_CODE_GPU_EXIT_ON_CONTEXT_LOST);
1173 else
1174 std::move(exit_callback_).Run(base::nullopt);
1175 }
1176
GetGpuScheduler()1177 gpu::Scheduler* GpuServiceImpl::GetGpuScheduler() {
1178 return scheduler_.get();
1179 }
1180
1181 #if defined(OS_WIN)
UpdateOverlayAndHDRInfo()1182 void GpuServiceImpl::UpdateOverlayAndHDRInfo() {
1183 gpu::OverlayInfo old_overlay_info = gpu_info_.overlay_info;
1184 gpu::CollectHardwareOverlayInfo(&gpu_info_.overlay_info);
1185
1186 // Update overlay info in the GPU process and send the updated data back to
1187 // the GPU host in the Browser process through mojom if the info has changed.
1188 if (old_overlay_info != gpu_info_.overlay_info)
1189 DidUpdateOverlayInfo(gpu_info_.overlay_info);
1190
1191 // Update HDR status in the GPU process through the GPU host mojom.
1192 bool old_hdr_enabled_status = hdr_enabled_;
1193 hdr_enabled_ = gl::DirectCompositionSurfaceWin::IsHDRSupported();
1194 if (old_hdr_enabled_status != hdr_enabled_)
1195 DidUpdateHDRStatus(hdr_enabled_);
1196 }
1197 #endif
1198
1199 } // namespace viz
1200