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 #ifndef COMPONENTS_VIZ_SERVICE_GL_GPU_SERVICE_IMPL_H_
6 #define COMPONENTS_VIZ_SERVICE_GL_GPU_SERVICE_IMPL_H_
7 
8 #include <memory>
9 #include <string>
10 
11 #include "base/callback.h"
12 #include "base/compiler_specific.h"
13 #include "base/memory/scoped_refptr.h"
14 #include "base/observer_list.h"
15 #include "base/single_thread_task_runner.h"
16 #include "base/synchronization/atomic_flag.h"
17 #include "base/synchronization/waitable_event.h"
18 #include "base/task/cancelable_task_tracker.h"
19 #include "base/threading/thread.h"
20 #include "build/build_config.h"
21 #include "components/viz/service/viz_service_export.h"
22 #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
23 #include "gpu/command_buffer/common/activity_flags.h"
24 #include "gpu/command_buffer/service/sequence_id.h"
25 #include "gpu/config/device_perf_info.h"
26 #include "gpu/config/gpu_extra_info.h"
27 #include "gpu/config/gpu_info.h"
28 #include "gpu/config/gpu_preferences.h"
29 #include "gpu/ipc/common/surface_handle.h"
30 #include "gpu/ipc/service/gpu_channel.h"
31 #include "gpu/ipc/service/gpu_channel_manager.h"
32 #include "gpu/ipc/service/gpu_channel_manager_delegate.h"
33 #include "gpu/ipc/service/gpu_config.h"
34 #include "gpu/ipc/service/x_util.h"
35 #include "gpu/vulkan/buildflags.h"
36 #include "mojo/public/cpp/bindings/pending_receiver.h"
37 #include "mojo/public/cpp/bindings/receiver.h"
38 #include "mojo/public/cpp/bindings/remote.h"
39 #include "mojo/public/cpp/bindings/shared_remote.h"
40 #include "services/viz/privileged/mojom/gl/gpu_host.mojom.h"
41 #include "services/viz/privileged/mojom/gl/gpu_service.mojom.h"
42 #include "skia/buildflags.h"
43 #include "third_party/skia/include/core/SkRefCnt.h"
44 #include "ui/gfx/native_widget_types.h"
45 
46 #if defined(OS_CHROMEOS)
47 namespace arc {
48 class ProtectedBufferManager;
49 }
50 #endif  // OS_CHROMEOS
51 
52 namespace gpu {
53 class GpuMemoryBufferFactory;
54 class GpuWatchdogThread;
55 class ImageDecodeAcceleratorWorker;
56 class Scheduler;
57 class SyncPointManager;
58 class SharedImageManager;
59 class VulkanImplementation;
60 }  // namespace gpu
61 
62 namespace media {
63 class MediaGpuChannelManager;
64 }
65 
66 namespace gpu {
67 class SharedContextState;
68 }  // namespace gpu
69 
70 namespace viz {
71 
72 class VulkanContextProvider;
73 class MetalContextProvider;
74 class DawnContextProvider;
75 
76 // This runs in the GPU process, and communicates with the gpu host (which is
77 // the window server) over the mojom APIs. This is responsible for setting up
78 // the connection to clients, allocating/free'ing gpu memory etc.
79 class VIZ_SERVICE_EXPORT GpuServiceImpl : public gpu::GpuChannelManagerDelegate,
80                                           public mojom::GpuService {
81  public:
82   GpuServiceImpl(const gpu::GPUInfo& gpu_info,
83                  std::unique_ptr<gpu::GpuWatchdogThread> watchdog,
84                  scoped_refptr<base::SingleThreadTaskRunner> io_runner,
85                  const gpu::GpuFeatureInfo& gpu_feature_info,
86                  const gpu::GpuPreferences& gpu_preferences,
87                  const base::Optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu,
88                  const base::Optional<gpu::GpuFeatureInfo>&
89                      gpu_feature_info_for_hardware_gpu,
90                  const gpu::GpuExtraInfo& gpu_extra_info,
91                  const base::Optional<gpu::DevicePerfInfo>& device_perf_info,
92                  gpu::VulkanImplementation* vulkan_implementation,
93                  base::OnceCallback<void(bool /*immediately*/)> exit_callback);
94 
95   ~GpuServiceImpl() override;
96 
97   void UpdateGPUInfo();
98 
99   void InitializeWithHost(
100       mojo::PendingRemote<mojom::GpuHost> gpu_host,
101       gpu::GpuProcessActivityFlags activity_flags,
102       scoped_refptr<gl::GLSurface> default_offscreen_surface,
103       gpu::SyncPointManager* sync_point_manager = nullptr,
104       gpu::SharedImageManager* shared_image_manager = nullptr,
105       base::WaitableEvent* shutdown_event = nullptr);
106   void Bind(mojo::PendingReceiver<mojom::GpuService> pending_receiver);
107 
108   scoped_refptr<gpu::SharedContextState> GetContextState();
109 
110   // Notifies the GpuHost to stop using GPU compositing. This should be called
111   // in response to an error in the GPU process that occurred after
112   // InitializeWithHost() was called, otherwise GpuFeatureInfo should be set
113   // accordingly. This can safely be called from any thread.
114   void DisableGpuCompositing();
115 
116   // mojom::GpuService:
117   void EstablishGpuChannel(int32_t client_id,
118                            uint64_t client_tracing_id,
119                            bool is_gpu_host,
120                            bool cache_shaders_on_disk,
121                            EstablishGpuChannelCallback callback) override;
122   void CloseChannel(int32_t client_id) override;
123 #if defined(OS_CHROMEOS)
124   void CreateArcVideoDecodeAccelerator(
125       mojo::PendingReceiver<arc::mojom::VideoDecodeAccelerator> vda_receiver)
126       override;
127   void CreateArcVideoEncodeAccelerator(
128       mojo::PendingReceiver<arc::mojom::VideoEncodeAccelerator> vea_receiver)
129       override;
130   void CreateArcVideoProtectedBufferAllocator(
131       mojo::PendingReceiver<arc::mojom::VideoProtectedBufferAllocator>
132           pba_receiver) override;
133   void CreateArcProtectedBufferManager(
134       mojo::PendingReceiver<arc::mojom::ProtectedBufferManager> pbm_receiver)
135       override;
136   void CreateJpegDecodeAccelerator(
137       mojo::PendingReceiver<chromeos_camera::mojom::MjpegDecodeAccelerator>
138           jda_receiver) override;
139   void CreateJpegEncodeAccelerator(
140       mojo::PendingReceiver<chromeos_camera::mojom::JpegEncodeAccelerator>
141           jea_receiver) override;
142 #endif  // defined(OS_CHROMEOS)
143 
144   void CreateVideoEncodeAcceleratorProvider(
145       mojo::PendingReceiver<media::mojom::VideoEncodeAcceleratorProvider>
146           vea_provider_receiver) override;
147   void CreateGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
148                              const gfx::Size& size,
149                              gfx::BufferFormat format,
150                              gfx::BufferUsage usage,
151                              int client_id,
152                              gpu::SurfaceHandle surface_handle,
153                              CreateGpuMemoryBufferCallback callback) override;
154   void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
155                               int client_id,
156                               const gpu::SyncToken& sync_token) override;
157   void GetVideoMemoryUsageStats(
158       GetVideoMemoryUsageStatsCallback callback) override;
159   void StartPeakMemoryMonitor(uint32_t sequence_num) override;
160   void GetPeakMemoryUsage(uint32_t sequence_num,
161                           GetPeakMemoryUsageCallback callback) override;
162 
163 #if defined(OS_WIN)
164   void RequestCompleteGpuInfo(RequestCompleteGpuInfoCallback callback) override;
165   void GetGpuSupportedRuntimeVersionAndDevicePerfInfo(
166       GetGpuSupportedRuntimeVersionAndDevicePerfInfoCallback callback) override;
167 #endif
168   void RequestHDRStatus(RequestHDRStatusCallback callback) override;
169   void LoadedShader(int32_t client_id,
170                     const std::string& key,
171                     const std::string& data) override;
172   void WakeUpGpu() override;
173   void GpuSwitched(gl::GpuPreference active_gpu_heuristic) override;
174   void DisplayAdded() override;
175   void DisplayRemoved() override;
176   void DestroyAllChannels() override;
177   void OnBackgroundCleanup() override;
178   void OnBackgrounded() override;
179   void OnForegrounded() override;
180 #if !defined(OS_ANDROID)
181   void OnMemoryPressure(
182       base::MemoryPressureListener::MemoryPressureLevel level) override;
183 #endif
184 #if defined(OS_MACOSX)
185   void BeginCATransaction() override;
186   void CommitCATransaction(CommitCATransactionCallback callback) override;
187 #endif
188   void Crash() override;
189   void Hang() override;
190   void ThrowJavaException() override;
191   void Stop(StopCallback callback) override;
192 
193   // gpu::GpuChannelManagerDelegate:
194   void RegisterDisplayContext(gpu::DisplayContext* display_context) override;
195   void UnregisterDisplayContext(gpu::DisplayContext* display_context) override;
196   void LoseAllContexts() override;
197   void DidCreateContextSuccessfully() override;
198   void DidCreateOffscreenContext(const GURL& active_url) override;
199   void DidDestroyChannel(int client_id) override;
200   void DidDestroyAllChannels() override;
201   void DidDestroyOffscreenContext(const GURL& active_url) override;
202   void DidLoseContext(bool offscreen,
203                       gpu::error::ContextLostReason reason,
204                       const GURL& active_url) override;
205 #if defined(OS_WIN)
206   void DidUpdateOverlayInfo(const gpu::OverlayInfo& overlay_info) override;
207 #endif
208   void StoreShaderToDisk(int client_id,
209                          const std::string& key,
210                          const std::string& shader) override;
211   void MaybeExitOnContextLost() override;
212   bool IsExiting() const override;
213   gpu::Scheduler* GetGpuScheduler() override;
214 
215 #if defined(OS_WIN)
216   void SendCreatedChildWindow(gpu::SurfaceHandle parent_window,
217                               gpu::SurfaceHandle child_window) override;
218 #endif
219 
220   // Installs a base::LogMessageHandlerFunction which ensures messages are sent
221   // to the mojom::GpuHost once InitializeWithHost() completes.
222   //
223   // In the event of aborted initialization, FlushPreInitializeLogMessages() may
224   // be called to flush the accumulated logs to the remote host.
225   //
226   // Note: ~GpuServiceImpl() will clear installed log handlers.
227   static void InstallPreInitializeLogHandler();
228   static void FlushPreInitializeLogMessages(mojom::GpuHost* gpu_host);
229 
is_initialized()230   bool is_initialized() const { return !!gpu_host_; }
231 
media_gpu_channel_manager()232   media::MediaGpuChannelManager* media_gpu_channel_manager() {
233     return media_gpu_channel_manager_.get();
234   }
235 
gpu_channel_manager()236   gpu::GpuChannelManager* gpu_channel_manager() {
237     return gpu_channel_manager_.get();
238   }
239 
240   gpu::ImageFactory* gpu_image_factory();
gpu_memory_buffer_factory()241   gpu::GpuMemoryBufferFactory* gpu_memory_buffer_factory() {
242     return gpu_memory_buffer_factory_.get();
243   }
244 
mailbox_manager()245   gpu::MailboxManager* mailbox_manager() {
246     return gpu_channel_manager_->mailbox_manager();
247   }
248 
shared_image_manager()249   gpu::SharedImageManager* shared_image_manager() {
250     return gpu_channel_manager_->shared_image_manager();
251   }
252 
share_group()253   gl::GLShareGroup* share_group() {
254     return gpu_channel_manager_->share_group();
255   }
256 
gr_shader_cache()257   gpu::raster::GrShaderCache* gr_shader_cache() {
258     return gpu_channel_manager_->gr_shader_cache();
259   }
260 
sync_point_manager()261   gpu::SyncPointManager* sync_point_manager() {
262     return gpu_channel_manager_->sync_point_manager();
263   }
264 
main_runner()265   scoped_refptr<base::SingleThreadTaskRunner>& main_runner() {
266     return main_runner_;
267   }
268 
watchdog_thread()269   gpu::GpuWatchdogThread* watchdog_thread() { return watchdog_thread_.get(); }
270 
gpu_feature_info()271   const gpu::GpuFeatureInfo& gpu_feature_info() const {
272     return gpu_feature_info_;
273   }
274 
in_host_process()275   bool in_host_process() const { return gpu_info_.in_process_gpu; }
276 
set_start_time(base::Time start_time)277   void set_start_time(base::Time start_time) { start_time_ = start_time; }
278 
gpu_info()279   const gpu::GPUInfo& gpu_info() const { return gpu_info_; }
gpu_preferences()280   const gpu::GpuPreferences& gpu_preferences() const {
281     return gpu_preferences_;
282   }
283 
284 #if BUILDFLAG(ENABLE_VULKAN)
is_using_vulkan()285   bool is_using_vulkan() const {
286     return !!vulkan_context_provider_ &&
287            gpu_preferences_.gr_context_type == gpu::GrContextType::kVulkan;
288   }
vulkan_context_provider()289   VulkanContextProvider* vulkan_context_provider() {
290     return vulkan_context_provider_.get();
291   }
292 #else
is_using_vulkan()293   bool is_using_vulkan() const { return false; }
vulkan_context_provider()294   VulkanContextProvider* vulkan_context_provider() { return nullptr; }
295 #endif
296 
297 #if BUILDFLAG(SKIA_USE_DAWN)
is_using_dawn()298   bool is_using_dawn() const { return !!dawn_context_provider_; }
dawn_context_provider()299   DawnContextProvider* dawn_context_provider() {
300     return dawn_context_provider_.get();
301   }
302 #else
is_using_dawn()303   bool is_using_dawn() const { return false; }
dawn_context_provider()304   DawnContextProvider* dawn_context_provider() { return nullptr; }
305 #endif
306 
307  private:
308   void RecordLogMessage(int severity,
309                         const std::string& header,
310                         const std::string& message);
311 
312   void UpdateGpuInfoPlatform(base::OnceClosure on_gpu_info_updated);
313 
314 #if defined(OS_CHROMEOS)
315   void CreateArcVideoDecodeAcceleratorOnMainThread(
316       mojo::PendingReceiver<arc::mojom::VideoDecodeAccelerator> vda_receiver);
317   void CreateArcVideoEncodeAcceleratorOnMainThread(
318       mojo::PendingReceiver<arc::mojom::VideoEncodeAccelerator> vea_receiver);
319   void CreateArcVideoProtectedBufferAllocatorOnMainThread(
320       mojo::PendingReceiver<arc::mojom::VideoProtectedBufferAllocator>
321           pba_receiver);
322   void CreateArcProtectedBufferManagerOnMainThread(
323       mojo::PendingReceiver<arc::mojom::ProtectedBufferManager> pbm_receiver);
324 #endif  // defined(OS_CHROMEOS)
325 
326   void RequestHDRStatusOnMainThread(RequestHDRStatusCallback callback);
327 
328   void OnBackgroundedOnMainThread();
329 
330   // Ensure that all peak memory tracking occurs on the main thread as all
331   // MemoryTracker are created on that thread. All requests made before
332   // GpuServiceImpl::InitializeWithHost will be enqueued.
333   void StartPeakMemoryMonitorOnMainThread(uint32_t sequence_num);
334   void GetPeakMemoryUsageOnMainThread(uint32_t sequence_num,
335                                       GetPeakMemoryUsageCallback callback);
336 
337   // Attempts to cleanly exit the process but only if not running in host
338   // process. If |for_context_loss| is true an error message will be logged.
339   void MaybeExit(bool for_context_loss);
340 
341   // Update overlay info on the GPU process and send the updated info back
342   // to the browser process if there is a change.
343 #if defined(OS_WIN)
344   void UpdateOverlayInfo();
345 #endif
346 
347   scoped_refptr<base::SingleThreadTaskRunner> main_runner_;
348   scoped_refptr<base::SingleThreadTaskRunner> io_runner_;
349 
350   // Do not change the class member order here. watchdog_thread_ should be the
351   // last one to be destroyed before main_runner_ and io_runner_.
352   std::unique_ptr<gpu::GpuWatchdogThread> watchdog_thread_;
353 
354   const gpu::GpuPreferences gpu_preferences_;
355 
356   // Information about the GPU, such as device and vendor ID.
357   gpu::GPUInfo gpu_info_;
358 
359   // Information about general chrome feature support for the GPU.
360   gpu::GpuFeatureInfo gpu_feature_info_;
361 
362   // What we would have gotten if we haven't fallen back to SwiftShader or
363   // pure software (in the viz case).
364   base::Optional<gpu::GPUInfo> gpu_info_for_hardware_gpu_;
365   base::Optional<gpu::GpuFeatureInfo> gpu_feature_info_for_hardware_gpu_;
366 
367   // Information about the GPU process populated on creation.
368   gpu::GpuExtraInfo gpu_extra_info_;
369 
370   // Information related to device perf category, only collected on the second
371   // unsandboxed GPU process.
372   base::Optional<gpu::DevicePerfInfo> device_perf_info_;
373 
374   mojo::SharedRemote<mojom::GpuHost> gpu_host_;
375   std::unique_ptr<gpu::GpuChannelManager> gpu_channel_manager_;
376   std::unique_ptr<media::MediaGpuChannelManager> media_gpu_channel_manager_;
377 
378   // On some platforms (e.g. android webview), the SyncPointManager and
379   // SharedImageManager comes from external sources.
380   std::unique_ptr<gpu::SyncPointManager> owned_sync_point_manager_;
381 
382   std::unique_ptr<gpu::SharedImageManager> owned_shared_image_manager_;
383 
384   std::unique_ptr<gpu::Scheduler> scheduler_;
385 
386 #if BUILDFLAG(ENABLE_VULKAN)
387   gpu::VulkanImplementation* vulkan_implementation_;
388   scoped_refptr<VulkanContextProvider> vulkan_context_provider_;
389 #endif
390   std::unique_ptr<MetalContextProvider> metal_context_provider_;
391 #if BUILDFLAG(SKIA_USE_DAWN)
392   std::unique_ptr<DawnContextProvider> dawn_context_provider_;
393 #endif
394 
395   std::unique_ptr<gpu::GpuMemoryBufferFactory> gpu_memory_buffer_factory_;
396 
397   // An event that will be signalled when we shutdown. On some platforms it
398   // comes from external sources.
399   std::unique_ptr<base::WaitableEvent> owned_shutdown_event_;
400   base::WaitableEvent* shutdown_event_ = nullptr;
401 
402   // Callback that safely exits GPU process.
403   base::OnceCallback<void(bool)> exit_callback_;
404   base::AtomicFlag is_exiting_;
405 
406   // Used for performing hardware decode acceleration of images. This is shared
407   // by all the GPU channels.
408   std::unique_ptr<gpu::ImageDecodeAcceleratorWorker>
409       image_decode_accelerator_worker_;
410 
411   base::Time start_time_;
412 
413   // Used to track the task to bind |receiver_| on the IO thread.
414   base::CancelableTaskTracker bind_task_tracker_;
415   // Should only be accessed on the IO thread after creation.
416   mojo::Receiver<mojom::GpuService> receiver_{this};
417 
418 #if defined(OS_CHROMEOS)
419   scoped_refptr<arc::ProtectedBufferManager> protected_buffer_manager_;
420 #endif  // defined(OS_CHROMEOS)
421 
422   // Display compositor contexts that don't have a corresponding GPU channel.
423   base::ObserverList<gpu::DisplayContext>::Unchecked display_contexts_;
424 
425   base::WeakPtr<GpuServiceImpl> weak_ptr_;
426   base::WeakPtrFactory<GpuServiceImpl> weak_ptr_factory_{this};
427 
428   DISALLOW_COPY_AND_ASSIGN(GpuServiceImpl);
429 };
430 
431 }  // namespace viz
432 
433 #endif  // COMPONENTS_VIZ_SERVICE_GL_GPU_SERVICE_IMPL_H_
434