chromium/content/browser/gpu/gpu_data_manager_impl_private.cc

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

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/342213636): Remove this and spanify to fix the errors.
#pragma allow_unsafe_buffers
#endif

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

#include "build/build_config.h"

#if BUILDFLAG(IS_WIN)
#include <windows.h>

#include <aclapi.h>
#include <sddl.h>
#endif  // BUILDFLAG(IS_WIN)

#include <array>
#include <iterator>
#include <memory>
#include <utility>

#include "base/command_line.h"
#include "base/debug/dump_without_crashing.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/path_service.h"
#include "base/rand_util.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_util.h"
#include "base/task/bind_post_task.h"
#include "base/trace_event/trace_event.h"
#include "base/version.h"
#include "build/chromecast_buildflags.h"
#include "build/chromeos_buildflags.h"
#include "cc/base/switches.h"
#include "components/viz/common/features.h"
#include "content/browser/gpu/gpu_memory_buffer_manager_singleton.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/media/frameless_media_interface_proxy.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/gpu_data_manager_observer.h"
#include "content/public/browser/gpu_utils.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/command_buffer/service/service_utils.h"
#include "gpu/config/gpu_blocklist.h"
#include "gpu/config/gpu_driver_bug_list.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
#include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_feature_type.h"
#include "gpu/config/gpu_finch_features.h"
#include "gpu/config/gpu_info_collector.h"
#include "gpu/config/gpu_preferences.h"
#include "gpu/config/gpu_switches.h"
#include "gpu/config/gpu_util.h"
#include "gpu/config/software_rendering_list_autogen.h"
#include "gpu/ipc/common/memory_stats.h"
#include "gpu/ipc/host/gpu_disk_cache.h"
#include "gpu/vulkan/buildflags.h"
#include "media/gpu/gpu_video_accelerator_util.h"
#include "media/media_buildflags.h"
#include "media/mojo/clients/mojo_video_decoder.h"
#include "media/mojo/mojom/video_encode_accelerator.mojom.h"
#include "ui/base/ui_base_switches.h"
#include "ui/display/screen.h"
#include "ui/gfx/switches.h"
#include "ui/gl/buildflags.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_switches.h"
#include "ui/gl/gpu_preference.h"
#include "ui/gl/gpu_switching_manager.h"

#if BUILDFLAG(IS_ANDROID)
#include "base/android/application_status_listener.h"
#endif
#if BUILDFLAG(IS_OZONE)
#include "ui/ozone/public/ozone_platform.h"
#endif
#if BUILDFLAG(IS_MAC)
#include <ApplicationServices/ApplicationServices.h>
#endif  // BUILDFLAG(IS_MAC)
#if BUILDFLAG(IS_WIN)
#include "base/base_paths_win.h"
#include "ui/display/win/screen_win.h"
#include "ui/gfx/mojom/dxgi_info.mojom.h"
#endif  // BUILDFLAG(IS_WIN)
#if BUILDFLAG(IS_CASTOS)
#include "chromecast/chromecast_buildflags.h"  // nogncheck
#endif                                         // BUILDFLAG(IS_CASTOS)

namespace content {

namespace {

// On X11, we do not know GpuMemoryBuffer configuration support until receiving
// the initial GPUInfo.
bool CanUpdateGmbGpuPreferences() {}

#if BUILDFLAG(IS_ANDROID)
// NOINLINE to ensure this function is used in crash reports.
NOINLINE void FatalGpuProcessLaunchFailureOnBackground() {
  if (!base::android::ApplicationStatusListener::HasVisibleActivities()) {
    // We expect the platform to aggressively kill services when the app is
    // backgrounded. A FATAL error creates a dialog notifying users that the
    // app has crashed which doesn't look good. So we use SIGKILL instead. But
    // still do a crash dump for 1% cases to make sure we're not regressing this
    // case.
    if (base::RandInt(1, 100) == 1)
      base::debug::DumpWithoutCrashing();
    kill(getpid(), SIGKILL);
  }
}
#endif

#if BUILDFLAG(IS_WIN)
// This function checks the created file to ensure it wasn't redirected
// to another location using a symbolic link or a hard link.
bool ValidateFileHandle(HANDLE cache_file_handle,
                        const base::FilePath& cache_file_path) {
  // Check that the file wasn't hardlinked to something else.
  BY_HANDLE_FILE_INFORMATION file_info = {};
  if (!::GetFileInformationByHandle(cache_file_handle, &file_info))
    return false;
  if (file_info.nNumberOfLinks > 1)
    return false;

  // Check the final path matches the expected path.
  wchar_t final_path_buffer[MAX_PATH];
  if (!::GetFinalPathNameByHandle(cache_file_handle, final_path_buffer,
                                  _countof(final_path_buffer),
                                  FILE_NAME_NORMALIZED | VOLUME_NAME_DOS)) {
    return false;
  }
  // Returned string should start with \\?\. If not then fail validation.
  if (!base::StartsWith(final_path_buffer, L"\\\\?\\",
                        base::CompareCase::INSENSITIVE_ASCII)) {
    return false;
  }
  // Expected filename and actual file name must be an exact match.
  return cache_file_path == base::FilePath(&final_path_buffer[4]);
}

// Generate Intel cache file names depending on the app name.
bool GetIntelCacheFileNames(std::vector<base::FilePath::StringType>* names) {
  DCHECK(names);
  DCHECK(names->empty());
  base::FilePath module_path;
  if (!base::PathService::Get(base::FILE_EXE, &module_path))
    return false;
  module_path = module_path.BaseName().RemoveExtension();
  base::FilePath::StringType module_name = module_path.value();
  if (module_name.size() == 0)
    return false;
  // The Intel shader cache files should be appName_[0|1|2].
  names->push_back(module_name + L"_0");
  names->push_back(module_name + L"_1");
  names->push_back(module_name + L"_2");
  return true;
}

void EnableIntelShaderCache() {
  base::FilePath dir;
  if (!base::PathService::Get(base::DIR_COMMON_APP_DATA, &dir))
    return;
  dir = dir.Append(L"Intel").Append(L"ShaderCache");
  if (!base::DirectoryExists(dir))
    return;

  PSECURITY_DESCRIPTOR sd = nullptr;
  ULONG sd_length = 0;
  // Set Full Access to All Users and Administrators, then grant RWX to
  // AppContainers and Low Privilege AppContainers.
  BOOL success = ::ConvertStringSecurityDescriptorToSecurityDescriptor(
      L"D:(A;;FA;;;AU)(A;;FA;;;BA)(A;;GRGWGX;;;S-1-15-2-1)(A;;GRGWGX;;;S-1-15-"
      L"2-2)",
      SDDL_REVISION_1, &sd, &sd_length);
  if (!success)
    return;
  DCHECK(sd);
  DCHECK_LT(0u, sd_length);
  std::unique_ptr<void, decltype(::LocalFree)*> sd_holder(sd, ::LocalFree);
  PACL dacl = nullptr;
  BOOL present = FALSE, defaulted = FALSE;
  success = ::GetSecurityDescriptorDacl(sd, &present, &dacl, &defaulted);
  if (!success)
    return;
  DCHECK(present);
  DCHECK(dacl);
  DCHECK(!defaulted);

  std::vector<base::FilePath::StringType> cache_file_names;
  if (!GetIntelCacheFileNames(&cache_file_names))
    return;
  for (const auto& cache_file_name : cache_file_names) {
    base::FilePath cache_file_path = dir.Append(cache_file_name);
    HANDLE cache_file_handle = ::CreateFileW(
        cache_file_path.value().c_str(), WRITE_DAC,
        FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, 0, nullptr);
    base::win::ScopedHandle handle_holder(cache_file_handle);
    if (cache_file_handle == INVALID_HANDLE_VALUE ||
        !ValidateFileHandle(cache_file_handle, cache_file_path)) {
      continue;
    }

    DWORD result = ::SetSecurityInfo(cache_file_handle, SE_KERNEL_OBJECT,
                                     DACL_SECURITY_INFORMATION, nullptr,
                                     nullptr, dacl, nullptr);
    if (result != ERROR_SUCCESS) {
      LOG(ERROR) << "SetSecurityInfo returned " << result;
    }
  }
}
#endif  // BUILDFLAG(IS_WIN)

// These values are persistent to logs. Entries should not be renumbered and
// numeric values should never be reused.
// This should match enum CanvasOopRasterAndGpuAcceleration in
//  \tools\metrics\histograms\enums.xml
enum class CanvasOopRasterAndGpuAcceleration {};

void RecordCanvasAcceleratedOopRasterHistogram(
    const gpu::GpuFeatureInfo& gpu_feature_info,
    bool gpu_compositing_disabled) {}

// Send UMA histograms about the enabled features and GPU properties.
void UpdateFeatureStats(const gpu::GpuFeatureInfo& gpu_feature_info) {}

void UpdateDriverBugListStats(const gpu::GpuFeatureInfo& gpu_feature_info) {}

#if BUILDFLAG(IS_MAC)
void DisplayReconfigCallback(CGDirectDisplayID display,
                             CGDisplayChangeSummaryFlags flags,
                             void* gpu_data_manager) {
  if (flags == kCGDisplayBeginConfigurationFlag)
    return;  // This call contains no information about the display change

  GpuDataManagerImpl* manager =
      reinterpret_cast<GpuDataManagerImpl*>(gpu_data_manager);
  DCHECK(manager);

  // Notification about "GPU switches" is only necessary on macOS when
  // using ANGLE's OpenGL backend. Short-circuit the dispatches for
  // all other backends.
  gpu::GPUInfo info = manager->GetGPUInfo();
  gl::GLImplementationParts parts = info.gl_implementation_parts;
  if (!(parts.gl == gl::kGLImplementationEGLANGLE &&
        parts.angle == gl::ANGLEImplementation::kOpenGL)) {
    return;
  }

  // Notification is only necessary if the machine actually has more
  // than one GPU - nowadays, defined by it being AMD switchable.
  if (!info.amd_switchable) {
    return;
  }

  // Dispatch the notification through the system.
  manager->HandleGpuSwitch();
}
#endif  // BUILDFLAG(IS_MAC)

void OnVideoMemoryUsageStats(
    GpuDataManager::VideoMemoryUsageStatsCallback callback,
    const gpu::VideoMemoryUsageStats& stats) {}

void RequestVideoMemoryUsageStats(
    GpuDataManager::VideoMemoryUsageStatsCallback callback,
    GpuProcessHost* host) {}

// Determines if SwiftShader is available as a fallback for WebGL.
bool SwiftShaderAllowed() {}

// These values are logged to UMA. Entries should not be renumbered and numeric
// values should never be reused. Please keep in sync with "CompositingMode" in
// src/tools/metrics/histograms/enums.xml.
enum class CompositingMode {};

// Intentionally crash with a very descriptive name.
NOINLINE void IntentionallyCrashBrowserForUnusableGpuProcess() {}

#if BUILDFLAG(IS_WIN)
void CollectExtraDevicePerfInfo(const gpu::GPUInfo& gpu_info,
                                gpu::DevicePerfInfo* device_perf_info) {
  device_perf_info->intel_gpu_generation = gpu::GetIntelGpuGeneration(gpu_info);
  const gpu::GPUInfo::GPUDevice& device = gpu_info.active_gpu();
  if (device.vendor_id == 0xffff /* internal flag for software rendering */ ||
      device.vendor_id == 0x15ad /* VMware */ ||
      device.vendor_id == 0x1414 /* Microsoft software renderer */ ||
      gl::IsSoftwareGLImplementation(
          gpu_info.gl_implementation_parts) /* SwiftShader */) {
    device_perf_info->software_rendering = true;
  }
}

// Provides a bridge whereby display::win::ScreenWin can ask the GPU process
// about the HDR status of the system.
class HDRProxy {
 public:
  static void Initialize() {
    display::win::ScreenWin::SetRequestHDRStatusCallback(
        base::BindRepeating(&HDRProxy::RequestHDRStatus));
  }

  static void RequestHDRStatus() {
    auto* gpu_process_host =
        GpuProcessHost::Get(GPU_PROCESS_KIND_SANDBOXED, false);
    if (gpu_process_host) {
      auto* gpu_service = gpu_process_host->gpu_host()->gpu_service();
      gpu_service->RequestDXGIInfo(base::BindOnce(&HDRProxy::GotResult));
    } else {
      GotResult(gfx::mojom::DXGIInfo::New());
    }
  }

  static void GotResult(gfx::mojom::DXGIInfoPtr dxgi_info) {
    display::win::ScreenWin::SetDXGIInfo(std::move(dxgi_info));
  }
};

#endif  // BUILDFLAG(IS_WIN)
}  // anonymous namespace

GpuDataManagerImplPrivate::GpuDataManagerImplPrivate(GpuDataManagerImpl* owner)
    :{}

GpuDataManagerImplPrivate::~GpuDataManagerImplPrivate() {}

void GpuDataManagerImplPrivate::StartUmaTimer() {}

void GpuDataManagerImplPrivate::InitializeGpuModes() {}

void GpuDataManagerImplPrivate::BlocklistWebGLForTesting() {}

void GpuDataManagerImplPrivate::SetSkiaGraphiteEnabledForTesting(bool enabled) {}

gpu::GPUInfo GpuDataManagerImplPrivate::GetGPUInfo() const {}

gpu::GPUInfo GpuDataManagerImplPrivate::GetGPUInfoForHardwareGpu() const {}

std::vector<std::string> GpuDataManagerImplPrivate::GetDawnInfoList() const {}

bool GpuDataManagerImplPrivate::GpuAccessAllowed(std::string* reason) const {}

bool GpuDataManagerImplPrivate::GpuAccessAllowedForHardwareGpu(
    std::string* reason) const {}

void GpuDataManagerImplPrivate::RequestDx12VulkanVideoGpuInfoIfNeeded(
    GpuDataManagerImpl::GpuInfoRequest request,
    bool delayed) {}

void GpuDataManagerImplPrivate::RequestGpuSupportedDirectXVersion(
    bool delayed) {}

void GpuDataManagerImplPrivate::RequestGpuSupportedVulkanVersion(bool delayed) {}

void GpuDataManagerImplPrivate::RequestDawnInfo(bool delayed,
                                                bool collect_metrics) {}

void GpuDataManagerImplPrivate::RequestMojoMediaVideoCapabilities() {}

bool GpuDataManagerImplPrivate::IsEssentialGpuInfoAvailable() const {}

bool GpuDataManagerImplPrivate::IsDx12VulkanVersionAvailable() const {}

bool GpuDataManagerImplPrivate::IsGpuFeatureInfoAvailable() const {}

gpu::GpuFeatureStatus GpuDataManagerImplPrivate::GetFeatureStatus(
    gpu::GpuFeatureType feature) const {}

void GpuDataManagerImplPrivate::RequestVideoMemoryUsageStatsUpdate(
    GpuDataManager::VideoMemoryUsageStatsCallback callback) const {}

void GpuDataManagerImplPrivate::AddObserver(GpuDataManagerObserver* observer) {}

void GpuDataManagerImplPrivate::RemoveObserver(
    GpuDataManagerObserver* observer) {}

void GpuDataManagerImplPrivate::UnblockDomainFrom3DAPIs(const GURL& url) {}

void GpuDataManagerImplPrivate::UpdateGpuInfo(
    const gpu::GPUInfo& gpu_info,
    const std::optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu) {}

#if BUILDFLAG(IS_WIN)

void GpuDataManagerImplPrivate::UpdateDirectXInfo(
    uint32_t d3d12_feature_level,
    uint32_t directml_feature_level) {
  gpu_info_.d3d12_feature_level = d3d12_feature_level;
  gpu_info_.directml_feature_level = directml_feature_level;
  gpu_info_dx_valid_ = true;
  // No need to call NotifyGpuInfoUpdate() because UpdateDirectXInfo() is
  // always called together with UpdateDevicePerfInfo, which calls
  // NotifyGpuInfoUpdate().
}

void GpuDataManagerImplPrivate::UpdateVulkanInfo(uint32_t vulkan_version) {
  gpu_info_.vulkan_version = vulkan_version;
  gpu_info_vulkan_valid_ = true;
  NotifyGpuInfoUpdate();
}

void GpuDataManagerImplPrivate::UpdateDevicePerfInfo(
    const gpu::DevicePerfInfo& device_perf_info) {
  gpu::DevicePerfInfo mutable_device_perf_info = device_perf_info;
  CollectExtraDevicePerfInfo(gpu_info_, &mutable_device_perf_info);
  gpu::SetDevicePerfInfo(mutable_device_perf_info);
  // No need to call GetContentClient()->SetGpuInfo().
  NotifyGpuInfoUpdate();
}

void GpuDataManagerImplPrivate::UpdateOverlayInfo(
    const gpu::OverlayInfo& overlay_info) {
  gpu_info_.overlay_info = overlay_info;

  // No need to call GetContentClient()->SetGpuInfo().
  NotifyGpuInfoUpdate();
}

void GpuDataManagerImplPrivate::UpdateDXGIInfo(
    gfx::mojom::DXGIInfoPtr dxgi_info) {
  // Calling out into HDRProxy::GotResult may end up re-entering us via
  // GpuDataManagerImpl::OnDisplayRemoved/OnDisplayAdded. Both of these
  // take the owner's lock. To avoid recursive locks, we PostTask
  // HDRProxy::GotResult so that it runs outside of the lock.
  GetUIThreadTaskRunner({})->PostTask(
      FROM_HERE, base::BindOnce(&HDRProxy::GotResult, std::move(dxgi_info)));
}

void GpuDataManagerImplPrivate::UpdateDirectXRequestStatus(
    bool request_continues) {
  gpu_info_dx_requested_ = true;
  gpu_info_dx_request_failed_ = !request_continues;

  if (gpu_info_dx_request_failed_) {
    gpu::DevicePerfInfo device_perf_info;
    gpu::CollectDevicePerfInfo(&device_perf_info, /*in_browser_process=*/true);
    UpdateDevicePerfInfo(device_perf_info);
  }
}

void GpuDataManagerImplPrivate::UpdateVulkanRequestStatus(
    bool request_continues) {
  gpu_info_vulkan_requested_ = true;
  gpu_info_vulkan_request_failed_ = !request_continues;
}

bool GpuDataManagerImplPrivate::DirectXRequested() const {
  return gpu_info_dx_requested_;
}

bool GpuDataManagerImplPrivate::VulkanRequested() const {
  return gpu_info_vulkan_requested_;
}

void GpuDataManagerImplPrivate::TerminateInfoCollectionGpuProcess() {
  // Wait until DX12/Vulkan and DevicePerfInfo requests are all complete.
  // gpu_info_dx12_valid_ is always updated before device_perf_info
  if (gpu_info_dx_requested_ && !gpu_info_dx_request_failed_ &&
      !gpu::GetDevicePerfInfo().has_value()) {
    return;
  }

  if (gpu_info_vulkan_requested_ && !gpu_info_vulkan_request_failed_ &&
      !gpu_info_vulkan_valid_)
    return;

  // GpuProcessHost::Get() calls GpuDataManagerImpl functions and causes a
  // re-entry of lock.
  base::AutoUnlock unlock(owner_->lock_);
  // GpuProcessHost::Get() only runs on the IO thread. Get() can be called
  // directly here from TerminateInfoCollectionGpuProcess(), which also runs on
  // the IO thread.
  GpuProcessHost* host = GpuProcessHost::Get(GPU_PROCESS_KIND_INFO_COLLECTION,
                                             false /* force_create */);
  if (host)
    host->ForceShutdown();
}
#endif

void GpuDataManagerImplPrivate::PostCreateThreads() {}

void GpuDataManagerImplPrivate::UpdateDawnInfo(
    const std::vector<std::string>& dawn_info_list) {}

void GpuDataManagerImplPrivate::UpdateGpuFeatureInfo(
    const gpu::GpuFeatureInfo& gpu_feature_info,
    const std::optional<gpu::GpuFeatureInfo>&
        gpu_feature_info_for_hardware_gpu) {}

void GpuDataManagerImplPrivate::UpdateGpuExtraInfo(
    const gfx::GpuExtraInfo& gpu_extra_info) {}

void GpuDataManagerImplPrivate::UpdateMojoMediaVideoDecoderCapabilities(
    const media::SupportedVideoDecoderConfigs& configs) {}

void GpuDataManagerImplPrivate::UpdateMojoMediaVideoEncoderCapabilities(
    const media::VideoEncodeAccelerator::SupportedProfiles& profiles) {}

gpu::GpuFeatureInfo GpuDataManagerImplPrivate::GetGpuFeatureInfo() const {}

gpu::GpuFeatureInfo GpuDataManagerImplPrivate::GetGpuFeatureInfoForHardwareGpu()
    const {}

gfx::GpuExtraInfo GpuDataManagerImplPrivate::GetGpuExtraInfo() const {}

bool GpuDataManagerImplPrivate::IsGpuCompositingDisabled() const {}

bool GpuDataManagerImplPrivate::IsGpuCompositingDisabledForHardwareGpu() const {}

void GpuDataManagerImplPrivate::SetGpuCompositingDisabled() {}

void GpuDataManagerImplPrivate::AppendGpuCommandLine(
    base::CommandLine* command_line,
    GpuProcessKind kind) const {}

void GpuDataManagerImplPrivate::UpdateGpuPreferences(
    gpu::GpuPreferences* gpu_preferences,
    GpuProcessKind kind) const {}

void GpuDataManagerImplPrivate::DisableHardwareAcceleration() {}

bool GpuDataManagerImplPrivate::HardwareAccelerationEnabled() const {}

void GpuDataManagerImplPrivate::OnGpuBlocked() {}

void GpuDataManagerImplPrivate::AddLogMessage(int level,
                                              const std::string& header,
                                              const std::string& message) {}

void GpuDataManagerImplPrivate::ProcessCrashed() {}

base::Value::List GpuDataManagerImplPrivate::GetLogMessages() const {}

void GpuDataManagerImplPrivate::HandleGpuSwitch() {}

void GpuDataManagerImplPrivate::OnDisplayAdded(
    const display::Display& new_display) {}

void GpuDataManagerImplPrivate::OnDisplaysRemoved(
    const display::Displays& removed_displays) {}

void GpuDataManagerImplPrivate::OnDisplayMetricsChanged(
    const display::Display& display,
    uint32_t changed_metrics) {}

void GpuDataManagerImplPrivate::BlockDomainsFrom3DAPIs(
    const std::set<GURL>& urls,
    gpu::DomainGuilt guilt) {}

bool GpuDataManagerImplPrivate::Are3DAPIsBlocked(const GURL& top_origin_url,
                                                 ThreeDAPIType requester) {}

void GpuDataManagerImplPrivate::DisableDomainBlockingFor3DAPIsForTesting() {}

void GpuDataManagerImplPrivate::NotifyGpuInfoUpdate() {}

bool GpuDataManagerImplPrivate::IsGpuProcessUsingHardwareGpu() const {}

void GpuDataManagerImplPrivate::SetApplicationVisible(bool is_visible) {}

std::string GpuDataManagerImplPrivate::GetDomainFromURL(const GURL& url) const {}

void GpuDataManagerImplPrivate::BlockDomainsFrom3DAPIsAtTime(
    const std::set<GURL>& urls,
    gpu::DomainGuilt guilt,
    base::Time at_time) {}

static const base::TimeDelta kBlockedDomainExpirationPeriod =;

void GpuDataManagerImplPrivate::ExpireOldBlockedDomainsAtTime(
    base::Time at_time) const {}

GpuDataManagerImplPrivate::DomainBlockStatus
GpuDataManagerImplPrivate::Are3DAPIsBlockedAtTime(const GURL& url,
                                                  base::Time at_time) const {}

base::TimeDelta GpuDataManagerImplPrivate::GetDomainBlockingExpirationPeriod()
    const {}

gpu::GpuMode GpuDataManagerImplPrivate::GetGpuMode() const {}

void GpuDataManagerImplPrivate::FallBackToNextGpuMode() {}

void GpuDataManagerImplPrivate::RecordCompositingMode() {}

#if BUILDFLAG(IS_LINUX)
bool GpuDataManagerImplPrivate::IsGpuMemoryBufferNV12Supported() {}
void GpuDataManagerImplPrivate::SetGpuMemoryBufferNV12Supported(
    bool supported) {}
#endif  // BUILDFLAG(IS_LINUX)

}  // namespace content