blob: 211864b50085790c1a5cb262ae88381d347b6fbd [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2012 The Chromium Authors
[email protected]a0421732011-02-23 03:55:402// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]d9f37932011-05-09 20:09:245#ifndef CONTENT_BROWSER_GPU_GPU_PROCESS_HOST_H_
6#define CONTENT_BROWSER_GPU_GPU_PROCESS_HOST_H_
[email protected]a0421732011-02-23 03:55:407
avib7348942015-12-25 20:57:108#include <stdint.h>
9
[email protected]f0170322011-04-26 06:41:1610#include <map>
dcheng59716272016-04-09 05:19:0811#include <memory>
[email protected]54947032012-12-08 01:44:0112#include <set>
[email protected]a82af392012-02-24 04:40:2013#include <string>
[email protected]f0170322011-04-26 06:41:1614
Zhenyao Moc4f79c32018-01-27 02:44:1315#include "base/atomicops.h"
Avi Drissmanadac21992023-01-11 23:46:3916#include "base/functional/callback.h"
Omar Elmekkawy859c02e2022-08-17 11:50:1117#include "base/location.h"
Sebastien Marchand9ea1262c2019-12-09 23:37:4318#include "base/memory/memory_pressure_listener.h"
[email protected]8c4b4db2013-03-19 00:51:4219#include "base/memory/weak_ptr.h"
[email protected]a43858f2013-06-28 15:18:3720#include "base/time/time.h"
avib7348942015-12-25 20:57:1021#include "build/build_config.h"
Mohsen Izadi0b9fbb62018-08-30 20:30:0022#include "components/viz/host/gpu_host_impl.h"
[email protected]8d128d62011-09-13 22:11:5723#include "content/common/content_export.h"
[email protected]4967f792012-01-20 22:14:4024#include "content/public/browser/browser_child_process_host_delegate.h"
[email protected]e1130502012-11-21 20:58:2725#include "content/public/browser/gpu_data_manager.h"
[email protected]54947032012-12-08 01:44:0126#include "gpu/command_buffer/common/constants.h"
Bo Liu01d003e42023-08-16 19:46:5027#include "gpu/command_buffer/common/shm_count.h"
ericrk41a1579e2017-02-10 20:56:2828#include "gpu/config/gpu_feature_info.h"
[email protected]d7b5cc72013-05-23 20:05:0029#include "gpu/config/gpu_info.h"
kylechar5d7fb33e2018-06-14 15:32:2530#include "gpu/config/gpu_mode.h"
Ken Rockot8322a042019-08-20 18:02:0031#include "mojo/public/cpp/bindings/generic_pending_receiver.h"
Julie Jeongeun Kim7b4a6aa12019-09-20 14:57:1232#include "mojo/public/cpp/bindings/pending_receiver.h"
Alex Gough4d173122021-08-24 21:18:2633#include "sandbox/policy/mojom/sandbox.mojom.h"
Miyoung Shin2be27f52019-07-27 15:35:3934#include "services/viz/privileged/mojom/compositing/frame_sink_manager.mojom.h"
35#include "services/viz/privileged/mojom/gl/gpu_host.mojom.h"
36#include "services/viz/privileged/mojom/gl/gpu_service.mojom.h"
37#include "services/viz/privileged/mojom/viz_main.mojom.h"
Alexander Dunaeve6e09c12020-10-23 16:43:4238#include "ui/gfx/gpu_extra_info.h"
[email protected]707e1c42013-07-09 21:18:5839#include "url/gurl.h"
[email protected]f0170322011-04-26 06:41:1640
Xiaohan Wang51dde9982022-01-14 18:37:4941#if BUILDFLAG(IS_WIN)
Maggie Chena6ece772020-04-27 17:19:0642#include "services/viz/privileged/mojom/gl/info_collection_gpu_service.mojom.h"
43#endif
44
gab4d92485f2016-09-26 21:00:4545namespace base {
46class Thread;
47}
48
[email protected]21efac32012-10-29 02:41:1149namespace content {
50class BrowserChildProcessHostImpl;
[email protected]d7a2d892013-08-16 07:45:3651
Xiaohan Wang51dde9982022-01-14 18:37:4952#if BUILDFLAG(IS_MAC)
Patrick Monette31020ea2023-03-10 01:48:3153class BrowserChildProcessBackgroundedBridge;
Sidney San Martín9387b402018-06-08 18:13:2654class CATransactionGPUCoordinator;
55#endif
56
Tom Sepezf3f28e12025-07-21 22:39:1357class GpuProcessHost final : public BrowserChildProcessHostDelegate,
58 public viz::GpuHostImpl::Delegate {
[email protected]a0421732011-02-23 03:55:4059 public:
Zhenyao Moc4f79c32018-01-27 02:44:1360 static int GetGpuCrashCount();
[email protected]63954792011-07-11 04:17:4861
sadrul6d310fa2016-08-04 02:12:1662 // Creates a new GpuProcessHost (if |force_create| is turned on) or gets an
63 // existing one, resulting in the launching of a GPU process if required.
64 // Returns null on failure. It is not safe to store the pointer once control
65 // has returned to the message loop as it can be destroyed. Instead store the
66 // associated GPU host ID. This could return NULL if GPU access is not
Corentin Wallez09c5fca2020-07-27 22:03:5867 // allowed (blocklisted).
sadrulca65d0702017-04-10 18:08:1368 CONTENT_EXPORT static GpuProcessHost* Get(
69 GpuProcessKind kind = GPU_PROCESS_KIND_SANDBOXED,
70 bool force_create = true);
[email protected]a0421732011-02-23 03:55:4071
Peter Boström9b036532021-10-28 23:37:2872 GpuProcessHost(const GpuProcessHost&) = delete;
73 GpuProcessHost& operator=(const GpuProcessHost&) = delete;
74
sadrulca65d0702017-04-10 18:08:1375 // Returns whether there is an active GPU process or not.
Nicholas Verne84dc55e2017-11-23 01:02:3876 static void GetHasGpuProcess(base::OnceCallback<void(bool)> callback);
[email protected]e1130502012-11-21 20:58:2777
Thiabaud Engelbrechte7ed1652023-06-04 21:42:3578 // Helper function to run a callback on the UI thread. The callback receives
sadrule6f6e102017-03-11 01:09:5679 // the appropriate GpuProcessHost instance. Note that the callback can be
80 // called with a null host (e.g. when |force_create| is false, and no
81 // GpuProcessHost instance exists).
Thiabaud Engelbrechte7ed1652023-06-04 21:42:3582 CONTENT_EXPORT static void CallOnUI(
Omar Elmekkawy859c02e2022-08-17 11:50:1183 const base::Location& location,
sadrulb428f6b2017-03-03 19:28:3284 GpuProcessKind kind,
85 bool force_create,
kylechared18a482019-02-07 14:07:2186 base::OnceCallback<void(GpuProcessHost*)> callback);
sadrul3ab0a5332017-03-01 03:16:4587
[email protected]a0421732011-02-23 03:55:4088 // Get the GPU process host for the GPU process with the given ID. Returns
89 // null if the process no longer exists.
90 static GpuProcessHost* FromID(int host_id);
[email protected]f0170322011-04-26 06:41:1691 int host_id() const { return host_id_; }
Mohsen Izadi0b9fbb62018-08-30 20:30:0092 base::ProcessId process_id() const { return process_id_; }
[email protected]a0421732011-02-23 03:55:4093
[email protected]7854d042012-03-15 19:08:1894 // What kind of GPU process, e.g. sandboxed or unsandboxed.
95 GpuProcessKind kind();
[email protected]6f1485ee2012-01-28 00:29:1996
derekjchow1b0f3bb2015-07-30 18:51:1097 // Forcefully terminates the GPU process.
[email protected]45aedeb2011-12-07 20:54:5398 void ForceShutdown();
99
Bo Liuae5b6def2020-06-01 19:44:51100 // Dumps the stack of the child process without crashing it.
101 // Only implemented on Android.
102 void DumpProcessStack();
103
Ken Rockot8322a042019-08-20 18:02:00104 // Asks the GPU process to run a service instance corresponding to the
Alex Gough4d173122021-08-24 21:18:26105 // specific interface receiver type carried by |receiver|. The interface must
106 // have the [ServiceSandbox=sandbox.mojom.Sandbox.kGpu] mojom attribute.
107 template <typename Interface>
108 void RunService(mojo::PendingReceiver<Interface> receiver) {
109 // Note: consult chrome-security before changing these asserts.
110 using ProvidedSandboxType = decltype(Interface::kServiceSandbox);
111 static_assert(
112 std::is_same<ProvidedSandboxType, const sandbox::mojom::Sandbox>::value,
113 "This interface does not declare a proper ServiceSandbox attribute. "
114 "See //docs/mojo_and_services.md (Specifying a sandbox).");
115 static_assert(Interface::kServiceSandbox == sandbox::mojom::Sandbox::kGpu,
116 "This interface must have [ServiceSandbox=kGpu].");
117 return RunServiceImpl(std::move(receiver));
118 }
Ken Rockot8322a042019-08-20 18:02:00119
Sadrul Habib Chowdhuryef1abe782017-08-01 17:20:38120 CONTENT_EXPORT viz::mojom::GpuService* gpu_service();
sadrul3ab0a5332017-03-01 03:16:45121
Xiaohan Wang51dde9982022-01-14 18:37:49122#if BUILDFLAG(IS_WIN)
Maggie Chena6ece772020-04-27 17:19:06123 CONTENT_EXPORT viz::mojom::InfoCollectionGpuService*
124 info_collection_gpu_service();
125#endif
126
Khushal9b937d82018-06-04 22:18:03127 CONTENT_EXPORT int GetIDForTesting() const;
128
Mohsen Izadi0b9fbb62018-08-30 20:30:00129 viz::GpuHostImpl* gpu_host() { return gpu_host_.get(); }
130
Patrick Monette31020ea2023-03-10 01:48:31131#if BUILDFLAG(IS_MAC)
132 BrowserChildProcessBackgroundedBridge*
133 browser_child_process_backgrounded_bridge_for_testing() {
134 return browser_child_process_backgrounded_bridge_.get();
135 }
136#endif
137
[email protected]a0421732011-02-23 03:55:40138 private:
Maksim Sisovcbdc9b32018-08-16 07:17:07139 enum class GpuTerminationOrigin {
140 kUnknownOrigin = 0,
141 kOzoneWaylandProxy = 1,
142 kMax = 2,
143 };
144
[email protected]de80ff202013-01-04 01:49:46145 static bool ValidateHost(GpuProcessHost* host);
[email protected]4967f792012-01-20 22:14:40146
Sean Gilhuly269cf4d22019-12-13 19:11:17147 // Increments |recent_crash_count_| by one. Before incrementing, remove one
148 // old crash for each forgiveness interval that has passed since the previous
149 // crash. If |gpu_mode| doesn't match |last_crash_mode_|, first reset the
150 // crash count.
151 static void IncrementCrashCount(gpu::GpuMode gpu_mode);
Mohsen Izadi35c8fbb2018-03-22 21:48:54152
[email protected]7854d042012-03-15 19:08:18153 GpuProcessHost(int host_id, GpuProcessKind kind);
dchengc2282aa2014-10-21 12:07:58154 ~GpuProcessHost() override;
[email protected]7a31f7c2011-03-21 23:22:04155
[email protected]a0421732011-02-23 03:55:40156 bool Init();
157
[email protected]4967f792012-01-20 22:14:40158 // BrowserChildProcessHostDelegate implementation.
dchengc2282aa2014-10-21 12:07:58159 void OnProcessLaunched() override;
wfh3adf87d2016-05-03 23:26:06160 void OnProcessLaunchFailed(int error_code) override;
dchengc2282aa2014-10-21 12:07:58161 void OnProcessCrashed(int exit_code) override;
[email protected]a0421732011-02-23 03:55:40162
Mohsen Izadi0b9fbb62018-08-30 20:30:00163 // viz::GpuHostImpl::Delegate:
164 gpu::GPUInfo GetGPUInfo() const override;
165 gpu::GpuFeatureInfo GetGpuFeatureInfo() const override;
Mohsen Izadif9505d82018-10-06 01:34:03166 void DidInitialize(
Zhenyao Mo68ef56d2018-04-21 01:05:10167 const gpu::GPUInfo& gpu_info,
168 const gpu::GpuFeatureInfo& gpu_feature_info,
Arthur Sonzognic686e8f2024-01-11 08:36:37169 const std::optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu,
170 const std::optional<gpu::GpuFeatureInfo>&
Jonah Ryan-Davisa70577c2019-06-26 18:54:31171 gpu_feature_info_for_hardware_gpu,
Alexander Dunaeve6e09c12020-10-23 16:43:42172 const gfx::GpuExtraInfo& gpu_extra_info) override;
sadrula235d7c2017-03-27 22:31:58173 void DidFailInitialize() override;
Bo Liud4194192017-11-28 22:30:14174 void DidCreateContextSuccessfully() override;
Bo Liu95570f32020-03-16 23:42:17175 void MaybeShutdownGpuProcess() override;
Jonah Ryan-Davisa54a3002020-12-08 17:34:50176 void DidUpdateGPUInfo(const gpu::GPUInfo& gpu_info) override;
Xiaohan Wang51dde9982022-01-14 18:37:49177#if BUILDFLAG(IS_WIN)
Maggie Chen8f177172020-02-11 00:02:28178 void DidUpdateOverlayInfo(const gpu::OverlayInfo& overlay_info) override;
Christopher Cameronb3ae6ff2022-05-02 18:11:00179 void DidUpdateDXGIInfo(gfx::mojom::DXGIInfoPtr dxgi_info) override;
Maggie Chen8f177172020-02-11 00:02:28180#endif
Loko Kung76d0dab2022-10-08 01:58:50181 std::string GetIsolationKey(
182 int32_t process_id,
183 const blink::WebGPUExecutionContextToken& token) override;
Kenneth Russell601ac282022-08-11 01:58:14184 void BlockDomainsFrom3DAPIs(const std::set<GURL>& urls,
185 gpu::DomainGuilt guilt) override;
kylecharf0a99352018-05-31 21:39:32186 void DisableGpuCompositing() override;
Mohsen Izadi0b9fbb62018-08-30 20:30:00187 bool GpuAccessAllowed() const override;
Loko Kunga2461bd2022-08-05 09:26:08188 gpu::GpuDiskCacheFactory* GetGpuDiskCacheFactory() override;
sadrul6aafa7d2017-03-22 22:56:35189 void RecordLogMessage(int32_t severity,
190 const std::string& header,
191 const std::string& message) override;
Julie Jeongeun Kim7b4a6aa12019-09-20 14:57:12192 void BindDiscardableMemoryReceiver(
193 mojo::PendingReceiver<
194 discardable_memory::mojom::DiscardableSharedMemoryManager> receiver)
Mohsen Izadi0b9fbb62018-08-30 20:30:00195 override;
Mohsen Izadi63d85e72018-09-06 16:00:21196 void BindInterface(const std::string& interface_name,
197 mojo::ScopedMessagePipeHandle interface_pipe) override;
Henrique Ferreiroc6c02e62019-09-17 09:39:02198 void BindHostReceiver(mojo::GenericPendingReceiver generic_receiver) override;
kylechar2d463872022-11-02 16:14:30199#if BUILDFLAG(IS_OZONE)
Mohsen Izadi63d85e72018-09-06 16:00:21200 void TerminateGpuProcess(const std::string& message) override;
Mohsen Izadi63d85e72018-09-06 16:00:21201#endif
sadrul550e264fd2017-02-14 03:44:57202
perryuwang82496fc92017-07-15 01:59:59203 bool LaunchGpuProcess();
[email protected]a0421732011-02-23 03:55:40204
Mohsen Izadibd50b1c2018-08-08 02:55:00205 void SendOutstandingReplies();
[email protected]f0170322011-04-26 06:41:16206
[email protected]54947032012-12-08 01:44:01207 void BlockLiveOffscreenContexts();
208
[email protected]47752982014-07-29 08:01:43209 // Update GPU crash counters. Disable GPU if crash limit is reached.
210 void RecordProcessCrash();
Bo Liu4bc773a2023-04-11 19:02:47211 int GetFallbackCrashLimit() const;
[email protected]47752982014-07-29 08:01:43212
Alex Gough4d173122021-08-24 21:18:26213 void RunServiceImpl(mojo::GenericPendingReceiver receiver);
214
Xiaohan Wang51dde9982022-01-14 18:37:49215#if !BUILDFLAG(IS_ANDROID)
Sebastien Marchand9ea1262c2019-12-09 23:37:43216 // Memory pressure handler, called by |memory_pressure_listener_|.
217 void OnMemoryPressure(
218 base::MemoryPressureListener::MemoryPressureLevel level);
219#endif
220
Zhenyao Mo32a85bd2019-06-07 19:27:12221 // The serial number of the GpuProcessHost.
[email protected]a0421732011-02-23 03:55:40222 int host_id_;
223
Mohsen Izadi0b9fbb62018-08-30 20:30:00224 // GPU process id in case GPU is not in-process.
225 base::ProcessId process_id_ = base::kNullProcessId;
226
[email protected]840a1d1a2012-08-04 00:26:19227 // Whether the GPU process is valid, set to false after Send() failed.
228 bool valid_;
229
[email protected]2d9de4112011-05-27 03:18:36230 // Whether we are running a GPU thread inside the browser process instead
231 // of a separate GPU process.
232 bool in_process_;
233
[email protected]7854d042012-03-15 19:08:18234 GpuProcessKind kind_;
[email protected]947f37482011-11-11 21:04:40235
kylechar5d7fb33e2018-06-14 15:32:25236 gpu::GpuMode mode_ = gpu::GpuMode::UNKNOWN;
237
[email protected]995f77362012-02-08 00:42:42238 // Whether we actually launched a GPU process.
239 bool process_launched_;
240
Maksim Sisovcbdc9b32018-08-16 07:17:07241 GpuTerminationOrigin termination_origin_ =
242 GpuTerminationOrigin::kUnknownOrigin;
243
[email protected]fb25bee2012-04-11 01:49:53244 // Time Init started. Used to log total GPU process startup time to UMA.
245 base::TimeTicks init_start_time_;
246
Antoine Labouree9dfa92018-11-13 19:32:09247 // The GPU process reported failure to initialize.
248 bool did_fail_initialize_ = false;
249
kylechar2dd7c412018-06-05 01:59:07250 // The total number of GPU process crashes.
Zhenyao Moc4f79c32018-01-27 02:44:13251 static base::subtle::Atomic32 gpu_crash_count_;
[email protected]47752982014-07-29 08:01:43252 static bool crashed_before_;
Sean Gilhuly269cf4d22019-12-13 19:11:17253 static int recent_crash_count_;
254 static gpu::GpuMode last_crash_mode_;
[email protected]47752982014-07-29 08:01:43255
Hugo Holgerssonf5f8cf92018-01-26 12:27:08256 // Here the bottom-up destruction order matters:
257 // The GPU thread depends on its host so stop the host last.
258 // Otherwise, under rare timings when the thread is still in Init(),
259 // it could crash as it fails to find a message pipe to the host.
dcheng59716272016-04-09 05:19:08260 std::unique_ptr<BrowserChildProcessHostImpl> process_;
Hugo Holgerssonf5f8cf92018-01-26 12:27:08261 std::unique_ptr<base::Thread> in_process_gpu_thread_;
[email protected]4967f792012-01-20 22:14:40262
Xiaohan Wang51dde9982022-01-14 18:37:49263#if BUILDFLAG(IS_MAC)
Sidney San Martín9387b402018-06-08 18:13:26264 scoped_refptr<CATransactionGPUCoordinator> ca_transaction_gpu_coordinator_;
Patrick Monette31020ea2023-03-10 01:48:31265
266 // Ensures the backgrounded state of the GPU process mirrors the backgrounded
267 // state of the browser process.
268 std::unique_ptr<BrowserChildProcessBackgroundedBridge>
269 browser_child_process_backgrounded_bridge_;
Sidney San Martín9387b402018-06-08 18:13:26270#endif
271
[email protected]54947032012-12-08 01:44:01272 // Track the URLs of the pages which have live offscreen contexts,
273 // assumed to be associated with untrusted content such as WebGL.
274 // For best robustness, when any context lost notification is
275 // received, assume all of these URLs are guilty, and block
276 // automatic execution of 3D content from those domains.
277 std::multiset<GURL> urls_with_live_offscreen_contexts_;
278
Xiaohan Wang51dde9982022-01-14 18:37:49279#if !BUILDFLAG(IS_ANDROID)
Sebastien Marchand9ea1262c2019-12-09 23:37:43280 // Responsible for forwarding the memory pressure notifications from the
281 // browser process to the GPU process.
282 std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
283#endif
284
Mohsen Izadi0b9fbb62018-08-30 20:30:00285 std::unique_ptr<viz::GpuHostImpl> gpu_host_;
sadrul6c5aed8c2017-01-11 23:11:44286
Jeremy Roman3bca4bf2019-07-11 03:41:25287 base::WeakPtrFactory<GpuProcessHost> weak_ptr_factory_{this};
[email protected]a0421732011-02-23 03:55:40288};
289
[email protected]21efac32012-10-29 02:41:11290} // namespace content
291
[email protected]d9f37932011-05-09 20:09:24292#endif // CONTENT_BROWSER_GPU_GPU_PROCESS_HOST_H_