1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
content / browser / gpu / gpu_data_manager_impl.h [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_H_
#define CONTENT_BROWSER_GPU_GPU_DATA_MANAGER_IMPL_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <string>
#include "base/no_destructor.h"
#include "base/process/kill.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "base/values.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/common/three_d_api_types.h"
#include "gpu/config/device_perf_info.h"
#include "gpu/config/gpu_control_list.h"
#include "gpu/config/gpu_domain_guilt.h"
#include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_info.h"
#include "gpu/config/gpu_mode.h"
#include "media/base/supported_video_decoder_config.h"
#include "media/video/video_encode_accelerator.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "third_party/blink/public/mojom/gpu/gpu.mojom.h"
#include "ui/display/display_observer.h"
#include "ui/gfx/gpu_extra_info.h"
#if BUILDFLAG(IS_WIN)
#include "ui/gfx/mojom/dxgi_info.mojom.h"
#endif
class GURL;
namespace gpu {
struct GpuPreferences;
}
namespace content {
class GpuDataManagerImplPrivate;
class CONTENT_EXPORT GpuDataManagerImpl : public GpuDataManager,
public display::DisplayObserver {
public:
enum GpuInfoRequest {
kGpuInfoRequestDirectX = 1 << 0,
kGpuInfoRequestVulkan = 1 << 1,
kGpuInfoRequestDawnInfo = 1 << 2,
kGpuInfoRequestDirectXVulkan =
kGpuInfoRequestVulkan | kGpuInfoRequestDirectX,
kGpuInfoRequestVideo = 1 << 3,
kGpuInfoRequestAll = kGpuInfoRequestDirectX | kGpuInfoRequestVulkan |
kGpuInfoRequestDawnInfo | kGpuInfoRequestVideo,
};
// Getter for the singleton. This will return NULL on failure.
static GpuDataManagerImpl* GetInstance();
GpuDataManagerImpl(const GpuDataManagerImpl&) = delete;
GpuDataManagerImpl& operator=(const GpuDataManagerImpl&) = delete;
// This returns true after the first call of GetInstance().
static bool Initialized();
// GpuDataManager implementation.
gpu::GPUInfo GetGPUInfo() override;
gpu::GpuFeatureStatus GetFeatureStatus(gpu::GpuFeatureType feature) override;
bool GpuAccessAllowed(std::string* reason) override;
bool IsEssentialGpuInfoAvailable() override;
void RequestVideoMemoryUsageStatsUpdate(
VideoMemoryUsageStatsCallback callback) override;
// TODO(kbr): the threading model for the GpuDataManagerObservers is
// not well defined, and it's impossible for callers to correctly
// delete observers from anywhere except in one of the observer's
// notification methods. Observer addition and removal, and their
// callbacks, should probably be required to occur on the UI thread.
void AddObserver(GpuDataManagerObserver* observer) override;
void RemoveObserver(GpuDataManagerObserver* observer) override;
void DisableHardwareAcceleration() override;
bool HardwareAccelerationEnabled() override;
void AppendGpuCommandLine(base::CommandLine* command_line,
GpuProcessKind kind) override;
void BlocklistWebGLForTesting() override;
void SetSkiaGraphiteEnabledForTesting(bool enabled) override;
// Start a timer that occasionally reports UMA metrics. This is explicitly
// started because unit tests may create and use a GpuDataManager but they do
// not want surprise tasks being posted which can interfere with their ability
// to measure what tasks are in the queue or to move mock time forward.
void StartUmaTimer();
// Requests complete GPU info if it has not already been requested
void RequestDx12VulkanVideoGpuInfoIfNeeded(
GpuDataManagerImpl::GpuInfoRequest request,
bool delayed);
bool IsDx12VulkanVersionAvailable() const;
bool IsGpuFeatureInfoAvailable() const;
void UpdateGpuInfo(
const gpu::GPUInfo& gpu_info,
const std::optional<gpu::GPUInfo>& 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
// Called from BrowserMainLoop::PostCreateThreads().
// TODO(content/browser/gpu/OWNERS): This should probably use a
// BrowserMainParts override instead.
void PostCreateThreads();
void UpdateDawnInfo(const std::vector<std::string>& dawn_info_list);
// Update the GPU feature info. This updates the blocklist and enabled status
// of GPU rasterization. In the future this will be used for more features.
void UpdateGpuFeatureInfo(const gpu::GpuFeatureInfo& gpu_feature_info,
const std::optional<gpu::GpuFeatureInfo>&
gpu_feature_info_for_hardware_gpu);
void UpdateGpuExtraInfo(const gfx::GpuExtraInfo& gpu_extra_info);
void UpdateMojoMediaVideoDecoderCapabilities(
const media::SupportedVideoDecoderConfigs& configs);
void UpdateMojoMediaVideoEncoderCapabilities(
const media::VideoEncodeAccelerator::SupportedProfiles&
supported_profiles);
gpu::GpuFeatureInfo GetGpuFeatureInfo() const;
// The following functions for cached GPUInfo and GpuFeatureInfo from the
// hardware GPU even if currently Chrome has fallen back to SwiftShader.
// Such info are displayed in about:gpu for diagostic purpose.
gpu::GPUInfo GetGPUInfoForHardwareGpu() const;
gpu::GpuFeatureInfo GetGpuFeatureInfoForHardwareGpu() const;
std::vector<std::string> GetDawnInfoList() const;
bool GpuAccessAllowedForHardwareGpu(std::string* reason);
bool IsGpuCompositingDisabledForHardwareGpu() const;
gfx::GpuExtraInfo GetGpuExtraInfo() const;
bool IsGpuCompositingDisabled() const;
// This only handles the state of GPU compositing. Instead call
// ImageTransportFactory::DisableGpuCompositing() to perform a fallback to
// software compositing.
void SetGpuCompositingDisabled();
// Update GpuPreferences based on blocklisting decisions.
void UpdateGpuPreferences(gpu::GpuPreferences* gpu_preferences,
GpuProcessKind kind) const;
void AddLogMessage(int level,
const std::string& header,
const std::string& message);
void ProcessCrashed();
// Returns a base::Value::List with the log messages.
base::Value::List GetLogMessages() const;
// Called when switching GPUs.
void HandleGpuSwitch();
// Maintenance of domains requiring explicit user permission before
// using client-facing 3D APIs (WebGL, Pepper 3D), either because
// the domain has caused the GPU to reset, or because too many GPU
// resets have been observed globally recently, and system stability
// might be compromised. A set of URLs is passed because in the
// situation where the GPU process crashes, the implementation needs
// to know that these URLs all came from the same crash.
//
// In the set, each URL may be a partial URL (including at least the
// host) or a full URL to a page.
void BlockDomainsFrom3DAPIs(const std::set<GURL>& urls,
gpu::DomainGuilt guilt);
bool Are3DAPIsBlocked(const GURL& top_origin_url,
ThreeDAPIType requester);
void UnblockDomainFrom3DAPIs(const GURL& url);
// Disables domain blocking for 3D APIs. For use only in tests.
void DisableDomainBlockingFor3DAPIsForTesting();
// Return mode describing what the GPU process will be launched to run.
gpu::GpuMode GetGpuMode() const;
// Called when GPU process initialization failed or the GPU process has
// crashed repeatedly. This will try to disable hardware acceleration and then
// SwiftShader WebGL. It will also crash the browser process as a last resort
// on Android and Chrome OS.
void FallBackToNextGpuMode();
// Check if there is at least one fallback option available.
bool CanFallback() const;
// Returns false if the latest GPUInfo gl_renderer is from SwiftShader or
// Disabled (in the viz case).
bool IsGpuProcessUsingHardwareGpu() const;
// State tracking allows us to customize GPU process launch depending on
// whether we are in the foreground or background.
void SetApplicationVisible(bool is_visible);
// DisplayObserver overrides.
void OnDisplayAdded(const display::Display& new_display) override;
void OnDisplaysRemoved(const display::Displays& removed_displays) override;
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) override;
#if BUILDFLAG(IS_LINUX)
bool IsGpuMemoryBufferNV12Supported();
void SetGpuMemoryBufferNV12Supported(bool supported);
#endif // BUILDFLAG(IS_LINUX)
// Binds a new Mojo receiver to handle requests from a renderer.
static void BindReceiver(
mojo::PendingReceiver<blink::mojom::GpuDataManager> receiver);
private:
friend class GpuDataManagerImplPrivate;
friend class GpuDataManagerImplPrivateTest;
friend class base::NoDestructor<GpuDataManagerImpl>;
GpuDataManagerImpl();
~GpuDataManagerImpl() override;
mutable base::Lock lock_;
std::unique_ptr<GpuDataManagerImplPrivate> private_ GUARDED_BY(lock_)
PT_GUARDED_BY(lock_);
};
} // namespace content
#endif // CONTENT_BROWSER_GPU_GPU_DATA_MANAGER_IMPL_H_