// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/gpu/gpu_data_manager_impl.h"

#include "base/no_destructor.h"
#include "build/build_config.h"
#include "content/browser/gpu/gpu_data_manager_impl_private.h"
#include "content/public/browser/browser_thread.h"
#include "gpu/ipc/common/memory_stats.h"
#include "mojo/public/cpp/bindings/receiver_set.h"

namespace content {

namespace {

bool g_initialized = false;

// Implementation of the Blink GpuDataManager interface to forward requests from
// a renderer to the GpuDataManagerImpl.
class GpuDataManagerReceiver : public blink::mojom::GpuDataManager {
 public:
  GpuDataManagerReceiver() = default;
  GpuDataManagerReceiver(const GpuDataManagerReceiver&) = delete;
  GpuDataManagerReceiver& operator=(const GpuDataManagerReceiver&) = delete;
  ~GpuDataManagerReceiver() override = default;

  void Bind(mojo::PendingReceiver<blink::mojom::GpuDataManager> receiver) {
    receivers_.Add(this, std::move(receiver));
  }

  // blink::mojom::GpuDataManager:
  void Are3DAPIsBlockedForUrl(
      const GURL& url,
      Are3DAPIsBlockedForUrlCallback callback) override {
    auto* manager = GpuDataManagerImpl::GetInstance();
    if (!manager) {
      std::move(callback).Run(false);
      return;
    }

    std::move(callback).Run(
        manager->Are3DAPIsBlocked(url, THREE_D_API_TYPE_WEBGL));
  }

 private:
  mojo::ReceiverSet<blink::mojom::GpuDataManager> receivers_;
};

GpuDataManagerReceiver& GetGpuDataManagerReceiver() {
  static base::NoDestructor<GpuDataManagerReceiver> receiver;
  return *receiver.get();
}

}  // namespace

// static
GpuDataManager* GpuDataManager::GetInstance() {
  return GpuDataManagerImpl::GetInstance();
}

// static
bool GpuDataManager::Initialized() {
  return GpuDataManagerImpl::Initialized();
}

// static
GpuDataManagerImpl* GpuDataManagerImpl::GetInstance() {
  static base::NoDestructor<GpuDataManagerImpl> instance;
  return instance.get();
}

// static
bool GpuDataManagerImpl::Initialized() {
  return g_initialized;
}

void GpuDataManagerImpl::BlocklistWebGLForTesting() {
  base::AutoLock auto_lock(lock_);
  private_->BlocklistWebGLForTesting();
}

gpu::GPUInfo GpuDataManagerImpl::GetGPUInfo() {
  base::AutoLock auto_lock(lock_);
  return private_->GetGPUInfo();
}

gpu::GpuFeatureStatus GpuDataManagerImpl::GetFeatureStatus(
    gpu::GpuFeatureType feature) {
  base::AutoLock auto_lock(lock_);
  return private_->GetFeatureStatus(feature);
}

bool GpuDataManagerImpl::GpuAccessAllowed(std::string* reason) {
  base::AutoLock auto_lock(lock_);
  return private_->GpuAccessAllowed(reason);
}

void GpuDataManagerImpl::RequestDxdiagDx12VulkanVideoGpuInfoIfNeeded(
    GpuInfoRequest request,
    bool delayed) {
  base::AutoLock auto_lock(lock_);
  private_->RequestDxdiagDx12VulkanVideoGpuInfoIfNeeded(request, delayed);
}

bool GpuDataManagerImpl::IsEssentialGpuInfoAvailable() {
  base::AutoLock auto_lock(lock_);
  return private_->IsEssentialGpuInfoAvailable();
}

bool GpuDataManagerImpl::IsDx12VulkanVersionAvailable() const {
  base::AutoLock auto_lock(lock_);
  return private_->IsDx12VulkanVersionAvailable();
}

bool GpuDataManagerImpl::IsGpuFeatureInfoAvailable() const {
  base::AutoLock auto_lock(lock_);
  return private_->IsGpuFeatureInfoAvailable();
}

void GpuDataManagerImpl::RequestVideoMemoryUsageStatsUpdate(
    VideoMemoryUsageStatsCallback callback) {
  base::AutoLock auto_lock(lock_);
  private_->RequestVideoMemoryUsageStatsUpdate(std::move(callback));
}

void GpuDataManagerImpl::AddObserver(GpuDataManagerObserver* observer) {
  base::AutoLock auto_lock(lock_);
  private_->AddObserver(observer);
}

void GpuDataManagerImpl::RemoveObserver(GpuDataManagerObserver* observer) {
  base::AutoLock auto_lock(lock_);
  private_->RemoveObserver(observer);
}

void GpuDataManagerImpl::DisableHardwareAcceleration() {
  base::AutoLock auto_lock(lock_);
  private_->DisableHardwareAcceleration();
}

bool GpuDataManagerImpl::HardwareAccelerationEnabled() {
  base::AutoLock auto_lock(lock_);
  return private_->HardwareAccelerationEnabled();
}

void GpuDataManagerImpl::AppendGpuCommandLine(base::CommandLine* command_line,
                                              GpuProcessKind kind) {
  base::AutoLock auto_lock(lock_);
  private_->AppendGpuCommandLine(command_line, kind);
}

void GpuDataManagerImpl::StartUmaTimer() {
  base::AutoLock auto_lock(lock_);
  private_->StartUmaTimer();
}

void GpuDataManagerImpl::UpdateGpuInfo(
    const gpu::GPUInfo& gpu_info,
    const absl::optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu) {
  base::AutoLock auto_lock(lock_);
  private_->UpdateGpuInfo(gpu_info, gpu_info_for_hardware_gpu);
}

#if BUILDFLAG(IS_WIN)
void GpuDataManagerImpl::UpdateDxDiagNode(
    const gpu::DxDiagNode& dx_diagnostics) {
  base::AutoLock auto_lock(lock_);
  private_->UpdateDxDiagNode(dx_diagnostics);
}

void GpuDataManagerImpl::UpdateDx12Info(uint32_t d3d12_feature_level) {
  base::AutoLock auto_lock(lock_);
  private_->UpdateDx12Info(d3d12_feature_level);
}

void GpuDataManagerImpl::UpdateVulkanInfo(uint32_t vulkan_version) {
  base::AutoLock auto_lock(lock_);
  private_->UpdateVulkanInfo(vulkan_version);
}

void GpuDataManagerImpl::UpdateDevicePerfInfo(
    const gpu::DevicePerfInfo& device_perf_info) {
  base::AutoLock auto_lock(lock_);
  private_->UpdateDevicePerfInfo(device_perf_info);
}

void GpuDataManagerImpl::UpdateOverlayInfo(
    const gpu::OverlayInfo& overlay_info) {
  base::AutoLock auto_lock(lock_);
  private_->UpdateOverlayInfo(overlay_info);
}
void GpuDataManagerImpl::UpdateDXGIInfo(gfx::mojom::DXGIInfoPtr dxgi_info) {
  base::AutoLock auto_lock(lock_);
  private_->UpdateDXGIInfo(std::move(dxgi_info));
}

void GpuDataManagerImpl::UpdateDxDiagNodeRequestStatus(bool request_continues) {
  base::AutoLock auto_lock(lock_);
  private_->UpdateDxDiagNodeRequestStatus(request_continues);
}

void GpuDataManagerImpl::UpdateDx12RequestStatus(bool request_continues) {
  base::AutoLock auto_lock(lock_);
  private_->UpdateDx12RequestStatus(request_continues);
}

void GpuDataManagerImpl::UpdateVulkanRequestStatus(bool request_continues) {
  base::AutoLock auto_lock(lock_);
  private_->UpdateVulkanRequestStatus(request_continues);
}

bool GpuDataManagerImpl::Dx12Requested() const {
  base::AutoLock auto_lock(lock_);
  return private_->Dx12Requested();
}

bool GpuDataManagerImpl::VulkanRequested() const {
  base::AutoLock auto_lock(lock_);
  return private_->VulkanRequested();
}

void GpuDataManagerImpl::PostCreateThreads() {
  base::AutoLock auto_lock(lock_);
  private_->PostCreateThreads();
}

void GpuDataManagerImpl::TerminateInfoCollectionGpuProcess() {
  base::AutoLock auto_lock(lock_);
  private_->TerminateInfoCollectionGpuProcess();
}
#endif

void GpuDataManagerImpl::UpdateDawnInfo(
    const std::vector<std::string>& dawn_info_list) {
  base::AutoLock auto_lock(lock_);
  private_->UpdateDawnInfo(dawn_info_list);
}

void GpuDataManagerImpl::UpdateGpuFeatureInfo(
    const gpu::GpuFeatureInfo& gpu_feature_info,
    const absl::optional<gpu::GpuFeatureInfo>&
        gpu_feature_info_for_hardware_gpu) {
  base::AutoLock auto_lock(lock_);
  private_->UpdateGpuFeatureInfo(gpu_feature_info,
                                 gpu_feature_info_for_hardware_gpu);
}

void GpuDataManagerImpl::UpdateGpuExtraInfo(
    const gfx::GpuExtraInfo& gpu_extra_info) {
  base::AutoLock auto_lock(lock_);
  private_->UpdateGpuExtraInfo(gpu_extra_info);
}

void GpuDataManagerImpl::UpdateMojoMediaVideoDecoderCapabilities(
    const media::SupportedVideoDecoderConfigs& configs) {
  base::AutoLock auto_lock(lock_);
  private_->UpdateMojoMediaVideoDecoderCapabilities(configs);
}

void GpuDataManagerImpl::UpdateMojoMediaVideoEncoderCapabilities(
    const media::VideoEncodeAccelerator::SupportedProfiles&
        supported_profiles) {
  base::AutoLock auto_lock(lock_);
  private_->UpdateMojoMediaVideoEncoderCapabilities(supported_profiles);
}

gpu::GpuFeatureInfo GpuDataManagerImpl::GetGpuFeatureInfo() const {
  base::AutoLock auto_lock(lock_);
  return private_->GetGpuFeatureInfo();
}

gpu::GPUInfo GpuDataManagerImpl::GetGPUInfoForHardwareGpu() const {
  base::AutoLock auto_lock(lock_);
  return private_->GetGPUInfoForHardwareGpu();
}

gpu::GpuFeatureInfo GpuDataManagerImpl::GetGpuFeatureInfoForHardwareGpu()
    const {
  base::AutoLock auto_lock(lock_);
  return private_->GetGpuFeatureInfoForHardwareGpu();
}

std::vector<std::string> GpuDataManagerImpl::GetDawnInfoList() const {
  base::AutoLock auto_lock(lock_);
  return private_->GetDawnInfoList();
}

bool GpuDataManagerImpl::GpuAccessAllowedForHardwareGpu(std::string* reason) {
  base::AutoLock auto_lock(lock_);
  return private_->GpuAccessAllowedForHardwareGpu(reason);
}

bool GpuDataManagerImpl::IsGpuCompositingDisabledForHardwareGpu() const {
  base::AutoLock auto_lock(lock_);
  return private_->IsGpuCompositingDisabledForHardwareGpu();
}

gfx::GpuExtraInfo GpuDataManagerImpl::GetGpuExtraInfo() const {
  base::AutoLock auto_lock(lock_);
  return private_->GetGpuExtraInfo();
}

bool GpuDataManagerImpl::IsGpuCompositingDisabled() const {
  base::AutoLock auto_lock(lock_);
  return private_->IsGpuCompositingDisabled();
}

void GpuDataManagerImpl::SetGpuCompositingDisabled() {
  base::AutoLock auto_lock(lock_);
  private_->SetGpuCompositingDisabled();
}

void GpuDataManagerImpl::UpdateGpuPreferences(
    gpu::GpuPreferences* gpu_preferences,
    GpuProcessKind kind) const {
  base::AutoLock auto_lock(lock_);
  private_->UpdateGpuPreferences(gpu_preferences, kind);
}

void GpuDataManagerImpl::AddLogMessage(int level,
                                       const std::string& header,
                                       const std::string& message) {
  base::AutoLock auto_lock(lock_);
  private_->AddLogMessage(level, header, message);
}

void GpuDataManagerImpl::ProcessCrashed() {
  base::AutoLock auto_lock(lock_);
  private_->ProcessCrashed();
}

std::unique_ptr<base::ListValue> GpuDataManagerImpl::GetLogMessages() const {
  base::AutoLock auto_lock(lock_);
  return private_->GetLogMessages();
}

void GpuDataManagerImpl::HandleGpuSwitch() {
  base::AutoLock auto_lock(lock_);
  private_->HandleGpuSwitch();
}

void GpuDataManagerImpl::BlockDomainFrom3DAPIs(const GURL& url,
                                               gpu::DomainGuilt guilt) {
  base::AutoLock auto_lock(lock_);
  private_->BlockDomainFrom3DAPIs(url, guilt);
}

bool GpuDataManagerImpl::Are3DAPIsBlocked(const GURL& top_origin_url,
                                          ThreeDAPIType requester) {
  base::AutoLock auto_lock(lock_);
  return private_->Are3DAPIsBlocked(top_origin_url, requester);
}

void GpuDataManagerImpl::UnblockDomainFrom3DAPIs(const GURL& url) {
  base::AutoLock auto_lock(lock_);
  private_->UnblockDomainFrom3DAPIs(url);
}

void GpuDataManagerImpl::DisableDomainBlockingFor3DAPIsForTesting() {
  base::AutoLock auto_lock(lock_);
  private_->DisableDomainBlockingFor3DAPIsForTesting();
}

gpu::GpuMode GpuDataManagerImpl::GetGpuMode() const {
  base::AutoLock auto_lock(lock_);
  return private_->GetGpuMode();
}

void GpuDataManagerImpl::FallBackToNextGpuMode() {
  base::AutoLock auto_lock(lock_);
  private_->FallBackToNextGpuMode();
}

bool GpuDataManagerImpl::CanFallback() const {
  base::AutoLock auto_lock(lock_);
  return private_->CanFallback();
}

bool GpuDataManagerImpl::IsGpuProcessUsingHardwareGpu() const {
  base::AutoLock auto_lock(lock_);
  return private_->IsGpuProcessUsingHardwareGpu();
}

void GpuDataManagerImpl::SetApplicationVisible(bool is_visible) {
  base::AutoLock auto_lock(lock_);
  private_->SetApplicationVisible(is_visible);
}

void GpuDataManagerImpl::OnDisplayAdded(const display::Display& new_display) {
  base::AutoLock auto_lock(lock_);
  private_->OnDisplayAdded(new_display);
}

void GpuDataManagerImpl::OnDisplayRemoved(const display::Display& old_display) {
  base::AutoLock auto_lock(lock_);
  private_->OnDisplayRemoved(old_display);
}

void GpuDataManagerImpl::OnDisplayMetricsChanged(
    const display::Display& display,
    uint32_t changed_metrics) {
  base::AutoLock auto_lock(lock_);
  private_->OnDisplayMetricsChanged(display, changed_metrics);
}

// static
void GpuDataManagerImpl::BindReceiver(
    mojo::PendingReceiver<blink::mojom::GpuDataManager> receiver) {
  // This is intentionally always bound on the IO thread to ensure a low-latency
  // response to sync IPCs.
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  GetGpuDataManagerReceiver().Bind(std::move(receiver));
}

GpuDataManagerImpl::GpuDataManagerImpl()
    : private_(std::make_unique<GpuDataManagerImplPrivate>(this)) {
  g_initialized = true;
}

GpuDataManagerImpl::~GpuDataManagerImpl() = default;

}  // namespace content
