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