// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_VIZ_HOST_GPU_HOST_IMPL_H_
#define COMPONENTS_VIZ_HOST_GPU_HOST_IMPL_H_

#include <map>
#include <optional>
#include <set>
#include <string>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/process/process_handle.h"
#include "base/sequence_checker.h"
#include "base/task/single_thread_task_runner.h"
#include "base/timer/timer.h"
#include "base/values.h"
#include "build/build_config.h"
#include "components/discardable_memory/public/mojom/discardable_shared_memory_manager.mojom.h"
#include "components/viz/common/buildflags.h"
#include "components/viz/host/viz_host_export.h"
#include "components/viz/service/debugger/mojom/viz_debugger.mojom.h"
#include "gpu/command_buffer/common/shared_image_capabilities.h"
#include "gpu/command_buffer/common/shm_count.h"
#include "gpu/config/gpu_domain_guilt.h"
#include "gpu/ipc/common/gpu_disk_cache_type.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "services/service_manager/public/mojom/service.mojom.h"
#include "services/viz/privileged/mojom/compositing/frame_sink_manager.mojom.h"
#include "services/viz/privileged/mojom/gl/gpu_host.mojom.h"
#include "services/viz/privileged/mojom/gl/gpu_service.mojom.h"
#include "services/viz/privileged/mojom/viz_main.mojom.h"
#include "ui/gfx/gpu_extra_info.h"
#include "url/gurl.h"

#if BUILDFLAG(IS_WIN)
#include "services/viz/privileged/mojom/gl/info_collection_gpu_service.mojom.h"
#include "ui/gfx/mojom/dxgi_info.mojom.h"
#endif

namespace gfx {
struct FontRenderParams;
}

namespace gpu {
class GpuDiskCacheFactory;
class GpuDiskCache;
}  // namespace gpu

namespace viz {

class VIZ_HOST_EXPORT GpuHostImpl : public mojom::GpuHost
#if BUILDFLAG(USE_VIZ_DEBUGGER)
    ,
                                    public mojom::VizDebugOutput
#endif
{
 public:
  class VIZ_HOST_EXPORT Delegate {
   public:
    virtual gpu::GPUInfo GetGPUInfo() const = 0;
    virtual gpu::GpuFeatureInfo GetGpuFeatureInfo() const = 0;
    virtual void DidInitialize(
        const gpu::GPUInfo& gpu_info,
        const gpu::GpuFeatureInfo& gpu_feature_info,
        const std::optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu,
        const std::optional<gpu::GpuFeatureInfo>&
            gpu_feature_info_for_hardware_gpu,
        const gfx::GpuExtraInfo& gpu_extra_info) = 0;
    virtual void DidFailInitialize() = 0;
    virtual void DidCreateContextSuccessfully() = 0;
    virtual void MaybeShutdownGpuProcess() = 0;
    virtual void DidUpdateGPUInfo(const gpu::GPUInfo& gpu_info) = 0;
#if BUILDFLAG(IS_WIN)
    virtual void DidUpdateOverlayInfo(const gpu::OverlayInfo& overlay_info) = 0;
    virtual void DidUpdateDXGIInfo(gfx::mojom::DXGIInfoPtr dxgi_info) = 0;
#endif
    virtual void BlockDomainsFrom3DAPIs(const std::set<GURL>& urls,
                                        gpu::DomainGuilt guilt) = 0;
    virtual std::string GetIsolationKey(
        int32_t client_id,
        const blink::WebGPUExecutionContextToken& token) = 0;
    virtual void DisableGpuCompositing() = 0;
    virtual bool GpuAccessAllowed() const = 0;
    virtual gpu::GpuDiskCacheFactory* GetGpuDiskCacheFactory() = 0;
    virtual void RecordLogMessage(int32_t severity,
                                  const std::string& header,
                                  const std::string& message) = 0;
    virtual void BindDiscardableMemoryReceiver(
        mojo::PendingReceiver<
            discardable_memory::mojom::DiscardableSharedMemoryManager>
            receiver) = 0;
    virtual void BindInterface(
        const std::string& interface_name,
        mojo::ScopedMessagePipeHandle interface_pipe) = 0;
#if BUILDFLAG(IS_OZONE)
    virtual void TerminateGpuProcess(const std::string& message) = 0;
#endif

   protected:
    virtual ~Delegate() = default;
  };

  struct VIZ_HOST_EXPORT InitParams {
    InitParams();
    InitParams(InitParams&&);
    ~InitParams();

    // An ID that changes for each GPU restart.
    int restart_id = -1;

    // Whether caching GPU shader on disk is disabled or not.
    bool disable_gpu_shader_disk_cache = false;

    // A string representing the product name and version; used to build a
    // prefix for shader keys.
    std::string product;

    // Number of frames to CompositorFrame activation deadline.
    std::optional<uint32_t> deadline_to_synchronize_surfaces;

    // Task runner corresponding to the main thread.
    scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner;

    // Whether this GPU process is used for GPU info collection only.
    bool info_collection_gpu_process = false;

    // Whether the GPU service is running in the host process.
    bool gpu_service_running_in_process = false;
  };

  enum class EstablishChannelStatus {
    kGpuAccessDenied,  // GPU access was not allowed.
    kGpuHostInvalid,   // Request failed because the GPU host became invalid
                       // while processing the request (e.g. the GPU process
                       // may have been killed). The caller should normally
                       // make another request to establish a new channel.
    kSuccess,
  };
  using EstablishChannelCallback =
      base::OnceCallback<void(mojo::ScopedMessagePipeHandle,
                              const gpu::GPUInfo&,
                              const gpu::GpuFeatureInfo&,
                              const gpu::SharedImageCapabilities&,
                              EstablishChannelStatus)>;

  GpuHostImpl(Delegate* delegate,
              mojo::PendingRemote<mojom::VizMain> viz_main,
              InitParams params);

  GpuHostImpl(const GpuHostImpl&) = delete;
  GpuHostImpl& operator=(const GpuHostImpl&) = delete;

  ~GpuHostImpl() override;

  static void InitFontRenderParams(const gfx::FontRenderParams& params);
  static void ResetFontRenderParams();

  void SetProcessId(base::ProcessId pid);
  void OnProcessCrashed();

  // Adds a connection error handler for the GpuService.
  void AddConnectionErrorHandler(base::OnceClosure handler);

  void BlockLiveOffscreenContexts();

  // Connects to FrameSinkManager running in the Viz service.
  void ConnectFrameSinkManager(
      mojo::PendingReceiver<mojom::FrameSinkManager> receiver,
      mojo::PendingRemote<mojom::FrameSinkManagerClient> client,
      const DebugRendererSettings& debug_renderer_settings);

  // Tells the GPU service to create a new channel for communication with a
  // client. Once the GPU service responds asynchronously with the channel
  // handle and GPUInfo, we call the callback. If |sync| is true then the
  // callback will be run before this method returns, and note that the
  // browser GPU info data might not be initialized as well.
  void EstablishGpuChannel(int client_id,
                           uint64_t client_tracing_id,
                           bool is_gpu_host,
                           bool sync,
                           EstablishChannelCallback callback);
  void SetChannelClientPid(int client_id, base::ProcessId client_pid);
  void SetChannelDiskCacheHandle(int client_id,
                                 const gpu::GpuDiskCacheHandle& handle);
  void RemoveChannelDiskCacheHandles(int client_id);
  void CloseChannel(int client_id);

#if BUILDFLAG(USE_VIZ_DEBUGGER)
  // Command as a Json string that the visual debugging instance interprets as
  // stream filtering.
  void FilterVisualDebugStream(base::Value::Dict filter_data);

  // Establishes the connection between the visual debugging instance and the
  // output stream.
  void StartVisualDebugStream(
      base::RepeatingCallback<void(base::Value)> callback);

  void StopVisualDebugStream();
#endif

  void SendOutstandingReplies();

  void BindInterface(const std::string& interface_name,
                     mojo::ScopedMessagePipeHandle interface_pipe);

  mojom::GpuService* gpu_service();

#if BUILDFLAG(IS_WIN)
  mojom::InfoCollectionGpuService* info_collection_gpu_service();
  void AddChildWindow(gpu::SurfaceHandle parent_window,
                      gpu::SurfaceHandle child_window);
#endif

  void MaybeSendFontRenderParams();

 private:
  friend class GpuHostImplTestApi;

#if BUILDFLAG(IS_OZONE)
  void InitOzone();
  void TerminateGpuProcess(const std::string& message);
#endif  // BUILDFLAG(IS_OZONE)

  std::string GetShaderPrefixKey();

  void LoadedBlob(const gpu::GpuDiskCacheHandle& handle,
                  const std::string& key,
                  const std::string& data);
  void OnDiskCacheHandleDestoyed(const gpu::GpuDiskCacheHandle& handle);

  void OnChannelEstablished(
      int client_id,
      bool sync,
      mojo::ScopedMessagePipeHandle channel_handle,
      const gpu::GPUInfo& gpu_info,
      const gpu::GpuFeatureInfo& gpu_feature_info,
      const gpu::SharedImageCapabilities& shared_image_capabilities);
  void MaybeShutdownGpuProcess();

  // mojom::GpuHost:
  void DidInitialize(
      const gpu::GPUInfo& gpu_info,
      const gpu::GpuFeatureInfo& gpu_feature_info,
      const std::optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu,
      const std::optional<gpu::GpuFeatureInfo>&
          gpu_feature_info_for_hardware_gpu,
      const gfx::GpuExtraInfo& gpu_extra_info) override;
  void DidFailInitialize() override;
  void DidCreateContextSuccessfully() override;
  void DidCreateOffscreenContext(const GURL& url) override;
  void DidDestroyOffscreenContext(const GURL& url) override;
  void DidDestroyChannel(int32_t client_id) override;
  void DidDestroyAllChannels() override;
  void DidLoseContext(gpu::error::ContextLostReason reason,
                      const GURL& active_url) override;
  void DisableGpuCompositing() override;
  void DidUpdateGPUInfo(const gpu::GPUInfo& gpu_info) override;
#if BUILDFLAG(IS_WIN)
  void DidUpdateOverlayInfo(const gpu::OverlayInfo& overlay_info) override;
  void DidUpdateDXGIInfo(gfx::mojom::DXGIInfoPtr dxgi_info) override;
#endif
  void GetIsolationKey(int32_t client_id,
                       const blink::WebGPUExecutionContextToken& token,
                       GetIsolationKeyCallback cb) override;
  void StoreBlobToDisk(const gpu::GpuDiskCacheHandle& handle,
                       const std::string& key,
                       const std::string& blob) override;
  void RecordLogMessage(int32_t severity,
                        const std::string& header,
                        const std::string& message) override;
  void ClearGrShaderDiskCache() override;

  // Implements mojom::VizDebugOutput and is called by VizDebugger.
#if BUILDFLAG(USE_VIZ_DEBUGGER)
  void LogFrame(base::Value frame_data) override;
#endif

  // Can be modified in tests by GpuHostImplTestApi.
  raw_ptr<Delegate> delegate_;

  mojo::Remote<mojom::VizMain> viz_main_;
  const InitParams params_;

  mojo::Remote<mojom::GpuService> gpu_service_remote_;
#if BUILDFLAG(IS_WIN)
  mojo::Remote<mojom::InfoCollectionGpuService>
      info_collection_gpu_service_remote_;
#endif
  mojo::Receiver<mojom::GpuHost> gpu_host_receiver_{this};
  gpu::GpuProcessHostShmCount use_shader_cache_shm_count_;

#if BUILDFLAG(USE_VIZ_DEBUGGER)
  mojo::Receiver<mojom::VizDebugOutput> viz_debug_output_{this};
  base::RepeatingCallback<void(base::Value)> viz_debug_output_callback_;
#endif

  base::ProcessId pid_ = base::kNullProcessId;

  // List of connection error handlers for the GpuService.
  std::vector<base::OnceClosure> connection_error_handlers_;

  // Track the URLs of the pages which have live offscreen contexts, assumed to
  // be associated with untrusted content such as WebGL. For best robustness,
  // when any context lost notification is received, assume all of these URLs
  // are guilty, and block automatic execution of 3D content from those domains.
  std::multiset<GURL> urls_with_live_offscreen_contexts_;

  std::multimap<int32_t, scoped_refptr<gpu::GpuDiskCache>> client_id_to_caches_;
  std::string shader_prefix_key_;

  // These are the channel requests that we have already sent to the GPU
  // service, but haven't heard back about yet.
  base::flat_map<int, EstablishChannelCallback> channel_requests_;

  base::OneShotTimer shutdown_timeout_;

  SEQUENCE_CHECKER(sequence_checker_);

  base::WeakPtrFactory<GpuHostImpl> weak_ptr_factory_{this};
};

}  // namespace viz

#endif  // COMPONENTS_VIZ_HOST_GPU_HOST_IMPL_H_
