blob: 7da54b2eda001414b222e0110e2085a395c2d359 [file] [log] [blame]
// 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.
#ifndef CONTENT_BROWSER_GPU_GPU_DATA_MANAGER_IMPL_PRIVATE_H_
#define CONTENT_BROWSER_GPU_GPU_DATA_MANAGER_IMPL_PRIVATE_H_
#include <stddef.h>
#include <stdint.h>
#include <list>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list_threadsafe.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/values.h"
#include "build/build_config.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/common/content_export.h"
#include "media/base/supported_video_decoder_config.h"
#include "media/video/video_encode_accelerator.h"
#include "ui/display/display_observer.h"
#include "ui/gl/gpu_preference.h"
namespace base {
class CommandLine;
}
namespace content {
class CONTENT_EXPORT GpuDataManagerImplPrivate {
public:
explicit GpuDataManagerImplPrivate(GpuDataManagerImpl* owner);
GpuDataManagerImplPrivate(const GpuDataManagerImplPrivate&) = delete;
GpuDataManagerImplPrivate& operator=(const GpuDataManagerImplPrivate&) =
delete;
virtual ~GpuDataManagerImplPrivate();
void StartUmaTimer();
gpu::GPUInfo GetGPUInfo() const;
gpu::GPUInfo GetGPUInfoForHardwareGpu() const;
std::vector<std::string> GetDawnInfoList() const;
bool GpuAccessAllowed(std::string* reason) const;
bool GpuAccessAllowedForHardwareGpu(std::string* reason) const;
void RequestDx12VulkanVideoGpuInfoIfNeeded(
GpuDataManagerImpl::GpuInfoRequest request,
bool delayed);
bool IsEssentialGpuInfoAvailable() const;
bool IsDx12VulkanVersionAvailable() const;
bool IsGpuFeatureInfoAvailable() const;
gpu::GpuFeatureStatus GetFeatureStatus(gpu::GpuFeatureType feature) const;
void RequestVideoMemoryUsageStatsUpdate(
GpuDataManager::VideoMemoryUsageStatsCallback callback) const;
void AddObserver(GpuDataManagerObserver* observer);
void RemoveObserver(GpuDataManagerObserver* observer);
void UnblockDomainFrom3DAPIs(const GURL& url);
void DisableHardwareAcceleration();
bool HardwareAccelerationEnabled() const;
bool IsGpuRasterizationForUIEnabled() const;
void UpdateGpuInfo(
const gpu::GPUInfo& gpu_info,
const std::optional<gpu::GPUInfo>& optional_gpu_info_for_hardware_gpu);
#if BUILDFLAG(IS_WIN)
void UpdateDirectXInfo(uint32_t d3d12_feature_level,
uint32_t directml_feature_level);
void UpdateVulkanInfo(uint32_t vulkan_version);
void UpdateDevicePerfInfo(const gpu::DevicePerfInfo& device_perf_info);
void UpdateOverlayInfo(const gpu::OverlayInfo& overlay_info);
void UpdateDXGIInfo(gfx::mojom::DXGIInfoPtr dxgi_info);
void UpdateDirectXRequestStatus(bool request_continues);
void UpdateVulkanRequestStatus(bool request_continues);
bool DirectXRequested() const;
bool VulkanRequested() const;
void TerminateInfoCollectionGpuProcess();
#endif
void PostCreateThreads();
void UpdateDawnInfo(const std::vector<std::string>& dawn_info_list);
void UpdateGpuFeatureInfo(const gpu::GpuFeatureInfo& gpu_feature_info,
const std::optional<gpu::GpuFeatureInfo>&
gpu_feature_info_for_hardware_gpu);
void UpdateGpuExtraInfo(const gfx::GpuExtraInfo& process_info);
void UpdateMojoMediaVideoDecoderCapabilities(
const media::SupportedVideoDecoderConfigs& configs);
void UpdateMojoMediaVideoEncoderCapabilities(
const media::VideoEncodeAccelerator::SupportedProfiles&
supported_profiles);
gpu::GpuFeatureInfo GetGpuFeatureInfo() const;
gpu::GpuFeatureInfo GetGpuFeatureInfoForHardwareGpu() const;
gfx::GpuExtraInfo GetGpuExtraInfo() const;
bool IsGpuCompositingDisabled() const;
bool IsGpuCompositingDisabledForHardwareGpu() const;
void SetGpuCompositingDisabled();
void AppendGpuCommandLine(base::CommandLine* command_line,
GpuProcessKind kind) const;
void UpdateGpuPreferences(gpu::GpuPreferences* gpu_preferences,
GpuProcessKind kind) const;
void AddLogMessage(int level,
const std::string& header,
const std::string& message);
void ProcessCrashed();
base::Value::List GetLogMessages() const;
void HandleGpuSwitch();
void BlockDomainsFrom3DAPIs(const std::set<GURL>& urls,
gpu::DomainGuilt guilt);
bool Are3DAPIsBlocked(const GURL& top_origin_url,
ThreeDAPIType requester);
void Notify3DAPIBlocked(const GURL& top_origin_url,
int render_process_id,
int render_frame_id,
ThreeDAPIType requester);
gpu::GpuMode GetGpuMode() const;
void FallBackToNextGpuMode();
void FallBackToNextGpuModeDueToCrash();
bool CanFallback() const { return !fallback_modes_.empty(); }
bool IsGpuProcessUsingHardwareGpu() const;
void SetApplicationVisible(bool is_visible);
void OnDisplayAdded(const display::Display& new_display);
void OnDisplaysRemoved(const display::Displays& removed_displays);
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics);
#if BUILDFLAG(IS_LINUX)
bool IsGpuMemoryBufferNV12Supported();
#endif // BUILDFLAG(IS_LINUX)
void DisableDomainBlockingFor3DAPIsForTesting();
void BlocklistWebGLForTesting();
void SetSkiaGraphiteEnabledForTesting(bool enabled);
private:
friend class GpuDataManagerImplPrivateTest;
friend class GpuDataManagerImplPrivateTestP;
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
GpuInfoUpdate);
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTestP,
SingleContextLossDoesNotBlockDomain);
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTestP,
TwoContextLossesBlockDomain);
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTestP,
TwoSimultaneousContextLossesDoNotBlockDomain);
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTestP, DomainBlockExpires);
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTestP, UnblockDomain);
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTestP,
Domain1DoesNotBlockDomain2);
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTestP,
UnblockingDomain1DoesNotUnblockDomain2);
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTestP,
SimultaneousContextLossDoesNotBlock);
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTestP,
MultipleTDRsBlockAll);
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTestP, MultipleTDRsExpire);
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTestP,
MultipleTDRsCanBeUnblocked);
// Indicates the reason that access to a given client API (like
// WebGL) was blocked or not. This state is distinct from blocklisting of an
// entire feature.
enum class DomainBlockStatus {
kBlocked,
kAllDomainsBlocked,
kNotBlocked,
};
using GpuDataManagerObserverList =
base::ObserverListThreadSafe<GpuDataManagerObserver>;
struct LogMessage {
int level;
std::string header;
std::string message;
LogMessage(int _level,
const std::string& _header,
const std::string& _message)
: level(_level),
header(_header),
message(_message) { }
};
// GPUInfo related data that should stay the same value even after GPUInfo is
// updated. After GPU process restart different GPUInfo can be sent back to
// the browser so the values here will be used reset the fixed data.
struct FixedGpuInfo {
std::optional<bool> hardware_supports_vulkan;
};
// Decide the order of GPU process states, and go to the first one. This
// should only be called once, during initialization.
void InitializeGpuModes();
// Called when GPU access (hardware acceleration and swiftshader) becomes
// blocked.
void OnGpuBlocked();
// Helper to extract the domain from a given URL.
std::string GetDomainFromURL(const GURL& url) const;
// Implementation functions for blocking of 3D graphics APIs, used
// for unit testing.
void BlockDomainsFrom3DAPIsAtTime(const std::set<GURL>& url,
gpu::DomainGuilt guilt,
base::Time at_time);
void ExpireOldBlockedDomainsAtTime(base::Time at_time) const;
DomainBlockStatus Are3DAPIsBlockedAtTime(const GURL& url,
base::Time at_time) const;
base::TimeDelta GetDomainBlockingExpirationPeriod() const;
// Notify all observers whenever there is a GPU info update.
void NotifyGpuInfoUpdate();
void RequestGpuSupportedDirectXVersion(bool delayed);
void RequestGpuSupportedVulkanVersion(bool delayed);
void RequestDawnInfo(bool delayed, bool collect_metrics);
void RequestMojoMediaVideoCapabilities();
void RecordCompositingMode();
const raw_ptr<GpuDataManagerImpl> owner_;
gpu::GpuFeatureInfo gpu_feature_info_;
FixedGpuInfo fixed_gpu_info_;
gpu::GPUInfo gpu_info_;
gl::GpuPreference active_gpu_heuristic_ = gl::GpuPreference::kDefault;
#if BUILDFLAG(IS_WIN)
bool gpu_info_dx_valid_ = false;
bool gpu_info_dx_requested_ = false;
bool gpu_info_dx_request_failed_ = false;
bool gpu_info_vulkan_valid_ = false;
bool gpu_info_vulkan_requested_ = false;
bool gpu_info_vulkan_request_failed_ = false;
#endif
// The Dawn info queried from the GPU process.
std::vector<std::string> dawn_info_list_;
// What we would have gotten if we haven't fallen back to SwiftShader or
// pure software (in the viz case).
gpu::GpuFeatureInfo gpu_feature_info_for_hardware_gpu_;
gpu::GPUInfo gpu_info_for_hardware_gpu_;
bool is_gpu_compositing_disabled_for_hardware_gpu_ = false;
bool gpu_access_allowed_for_hardware_gpu_ = true;
std::string gpu_access_blocked_reason_for_hardware_gpu_;
gfx::GpuExtraInfo gpu_extra_info_;
const scoped_refptr<GpuDataManagerObserverList> observer_list_;
// Periodically calls RecordCompositingMode() for compositing mode UMA.
base::RepeatingTimer compositing_mode_timer_;
// Contains the 1000 most recent log messages.
std::vector<LogMessage> log_messages_;
// What the gpu process is being run for.
gpu::GpuMode gpu_mode_ = gpu::GpuMode::UNKNOWN;
// Order of gpu process fallback states, used as a stack.
std::vector<gpu::GpuMode> fallback_modes_;
std::optional<display::ScopedOptionalDisplayObserver> display_observer_;
// Used to tell if the gpu was disabled by an explicit call to
// DisableHardwareAcceleration(), rather than by fallback.
bool hardware_disabled_explicitly_ = false;
// We disable histogram stuff in testing, especially in unit tests because
// they cause random failures.
bool update_histograms_ = true;
struct DomainBlockingEntry {
DomainBlockingEntry(const std::string& domain, gpu::DomainGuilt guilt)
: domain(domain), guilt(guilt) {}
std::string domain;
gpu::DomainGuilt guilt;
};
// Implicitly sorted by increasing timestamp.
mutable std::multimap<base::Time, DomainBlockingEntry> blocked_domains_;
bool domain_blocking_enabled_ = true;
bool application_is_visible_ = true;
bool disable_gpu_compositing_ = false;
#if BUILDFLAG(IS_LINUX)
bool is_gpu_memory_buffer_NV12_supported_ = false;
#endif // BUILDFLAG(IS_LINUX)
bool is_gpu_rasterization_for_ui_enabled_ = true;
};
} // namespace content
#endif // CONTENT_BROWSER_GPU_GPU_DATA_MANAGER_IMPL_PRIVATE_H_