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