blob: 5c3bcea34087025ecab1959fd2d55fe5c5369142 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2012 The Chromium Authors
[email protected]c0fc0942010-01-13 00:55:372// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
avi66a07722015-12-25 23:38:125#include <stddef.h>
[email protected]e09cee42010-11-09 01:50:086#include <stdlib.h>
7
mostynb6682b1c42016-04-19 10:17:308#include <memory>
Avi Drissman9a3ed4e2022-01-26 14:15:379#include <tuple>
dchengf26eed32016-01-13 10:58:1410#include <utility>
11
Sebastien Marchandf8cbfab2019-01-25 16:02:3012#include "base/bind.h"
Joe Mason94bebf12022-06-03 15:03:5313#include "base/check.h"
Gabriel Charettef3851332022-04-28 23:39:1814#include "base/command_line.h"
Sunny Sachanandani5cd10e962019-06-13 22:55:3215#include "base/feature_list.h"
Keishi Hattori0e45c022021-11-27 09:25:5216#include "base/memory/raw_ptr.h"
Carlos Caballerodd8bf7b042019-07-30 14:14:1517#include "base/message_loop/message_pump_type.h"
asvitkine8d51e9d2016-09-02 23:55:4318#include "base/metrics/histogram_macros.h"
Jeff Chenfce90f32022-01-31 19:49:3419#include "base/numerics/clamped_math.h"
20#include "base/process/process_metrics.h"
[email protected]2436a6b2012-04-13 21:08:5121#include "base/rand_util.h"
fdoraye716a902016-07-05 16:05:4922#include "base/run_loop.h"
[email protected]d0ea4782013-06-11 04:58:2423#include "base/strings/string_number_conversions.h"
Sebastien Marchand75a7cdf2018-11-13 23:47:0324#include "base/system/sys_info.h"
Alex Clarke636e7052019-05-30 10:49:3725#include "base/task/single_thread_task_executor.h"
Joe Mason94bebf12022-06-03 15:03:5326#include "base/task/thread_pool/thread_pool_instance.h"
[email protected]ce072a72010-12-31 20:02:1627#include "base/threading/platform_thread.h"
Gabriel Charetted87f10f2022-03-31 00:44:2228#include "base/time/time.h"
stanisc61507092017-07-06 16:36:5829#include "base/timer/hi_res_timer_manager.h"
primiano50b7444c2015-01-28 04:17:0030#include "base/trace_event/trace_event.h"
[email protected]c0fc0942010-01-13 00:55:3731#include "build/build_config.h"
Yuta Hijikata76d5cb62020-12-09 09:51:5332#include "build/chromeos_buildflags.h"
Sadrul Habib Chowdhury55fc2f02017-10-27 02:40:0633#include "components/viz/service/main/viz_main_impl.h"
Joe Mason94bebf12022-06-03 15:03:5334#include "content/child/child_process.h"
[email protected]91a2aea2013-07-08 23:14:3935#include "content/common/content_constants_internal.h"
John Abd-El-Malek884291c2017-08-09 06:43:4836#include "content/common/content_switches_internal.h"
Benoit Lize7ee77d32021-03-04 17:26:1437#include "content/common/partition_alloc_support.h"
Khushala4e236f2018-06-01 03:00:4638#include "content/common/skia_utils.h"
[email protected]7a31f7c2011-03-21 23:22:0439#include "content/gpu/gpu_child_thread.h"
[email protected]c9e2cbbb2012-05-12 21:17:2740#include "content/public/common/content_client.h"
[email protected]c9e2cbbb2012-05-12 21:17:2741#include "content/public/common/content_switches.h"
42#include "content/public/common/main_function_params.h"
jbaumana19f1df2017-01-18 03:01:1743#include "content/public/common/result_codes.h"
Zhenyao Moc76e9032018-01-19 21:15:4644#include "content/public/gpu/content_gpu_client.h"
[email protected]40c19e722013-11-05 23:51:2445#include "gpu/command_buffer/service/gpu_switches.h"
sadruled395922016-09-07 17:32:5846#include "gpu/config/gpu_driver_bug_list.h"
Sunny Sachanandani5cd10e962019-06-13 22:55:3247#include "gpu/config/gpu_finch_features.h"
[email protected]d7b5cc72013-05-23 20:05:0048#include "gpu/config/gpu_info_collector.h"
Jonathan Backer16cc8fd2018-05-31 19:59:2249#include "gpu/config/gpu_preferences.h"
tfarina15525c42015-04-28 19:04:1650#include "gpu/config/gpu_switches.h"
[email protected]40c19e722013-11-05 23:51:2451#include "gpu/config/gpu_util.h"
fsamuelc2774222016-03-24 00:27:1252#include "gpu/ipc/common/gpu_memory_buffer_support.h"
markdittmerd88b8352016-04-08 15:28:4553#include "gpu/ipc/service/gpu_config.h"
sadrul454af3332016-09-09 18:14:3254#include "gpu/ipc/service/gpu_init.h"
sadrul2fb7e152016-08-30 05:21:4555#include "gpu/ipc/service/gpu_watchdog_thread.h"
Scott Violeta35f9a42018-03-22 22:00:4456#include "media/gpu/buildflags.h"
kylechar60e12ed2021-03-15 15:56:0357#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
Dale Curtis12cfe022020-02-21 01:18:4258#include "services/tracing/public/cpp/trace_startup.h"
Tom Sepeza0950c62017-10-18 20:39:1459#include "third_party/angle/src/gpu_info_util/SystemInfo.h"
Maksim Sisov459eada2020-06-25 08:16:3160#include "ui/base/ui_base_features.h"
[email protected]c0939182014-05-24 00:09:1961#include "ui/events/platform/platform_event_source.h"
skyostilb354f882016-12-13 18:42:4562#include "ui/gfx/switches.h"
martina.kollarovaa34211d2015-06-25 11:49:0763#include "ui/gl/gl_context.h"
[email protected]db6101db2012-10-25 15:20:0864#include "ui/gl/gl_implementation.h"
[email protected]c9e2cbbb2012-05-12 21:17:2765#include "ui/gl/gl_surface.h"
66#include "ui/gl/gl_switches.h"
[email protected]1bb06b02012-09-23 19:37:2467#include "ui/gl/gpu_switching_manager.h"
kylechar5b9dec12016-05-16 15:40:5768#include "ui/gl/init/gl_factory.h"
[email protected]c0fc0942010-01-13 00:55:3769
Xiaohan Wang62737b52022-01-15 18:09:0270#if BUILDFLAG(IS_WIN)
fdoraye716a902016-07-05 16:05:4971#include <dwmapi.h>
Benoit Lize7ee77d32021-03-04 17:26:1472#include <windows.h>
avi66a07722015-12-25 23:38:1273#endif
74
Xiaohan Wang62737b52022-01-15 18:09:0275#if BUILDFLAG(IS_ANDROID)
primianob3fb6412015-10-14 16:03:5176#include "base/trace_event/memory_dump_manager.h"
primianoccb26c62016-06-01 21:50:0277#include "components/tracing/common/graphics_memory_dump_provider_android.h"
primianob3fb6412015-10-14 16:03:5178#endif
79
Xiaohan Wang62737b52022-01-15 18:09:0280#if BUILDFLAG(IS_WIN)
Daniel Libby8f7e6262019-01-08 22:35:5581#include "base/trace_event/trace_event_etw_export_win.h"
[email protected]5f7e4512012-10-01 20:51:3782#include "base/win/scoped_com_initializer.h"
Bill Carrba4cbb972022-10-10 18:24:1183#include "base/win/win_util.h"
kylechar5b9dec12016-05-16 15:40:5784#include "base/win/windows_version.h"
Miguel Casasd697adf32018-02-26 19:06:3185#include "media/gpu/windows/dxva_video_decode_accelerator_win.h"
86#include "media/gpu/windows/media_foundation_video_encode_accelerator_win.h"
[email protected]181491782012-07-18 00:59:1587#include "sandbox/win/src/sandbox.h"
[email protected]802a13a02010-12-02 01:48:3788#endif
89
Xiaohan Wang62737b52022-01-15 18:09:0290#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
Tom Sepez085507ab2017-10-18 22:36:0091#include "content/gpu/gpu_sandbox_hook_linux.h"
Robert Sesek7d0b49b2020-07-08 18:31:2792#include "sandbox/policy/linux/sandbox_linux.h"
Alex Gougheb6a38f2021-10-22 01:55:1393#include "sandbox/policy/sandbox_type.h"
[email protected]2436a6b2012-04-13 21:08:5194#endif
95
Xiaohan Wang62737b52022-01-15 18:09:0296#if BUILDFLAG(IS_MAC)
[email protected]826aab02014-05-14 02:58:5997#include "base/message_loop/message_pump_mac.h"
Kai Ninomiyae2c55582019-12-19 23:51:0398#include "components/metal_util/device_removal.h"
Christopher Cameron21c4abc2019-11-15 04:06:1599#include "components/metal_util/test_shader.h"
Robert Sesek3bd6e4b32019-11-26 16:02:27100#include "media/gpu/mac/vt_video_decode_accelerator_mac.h"
Greg Kerr3480aa82018-02-01 00:53:03101#include "sandbox/mac/seatbelt.h"
[email protected]826aab02014-05-14 02:58:59102#endif
103
Alexandre Courbotc13a5972017-07-23 03:48:48104#if BUILDFLAG(USE_VAAPI)
Miguel Casas42e955c2017-12-04 14:18:12105#include "media/gpu/vaapi/vaapi_wrapper.h"
hshi95837052015-05-12 15:39:51106#endif
107
[email protected]eb398192012-10-22 20:16:19108namespace content {
[email protected]ec4bda62013-06-14 15:51:03109
[email protected]6ec3a572012-08-17 02:09:51110namespace {
[email protected]ec4bda62013-06-14 15:51:03111
Xiaohan Wang62737b52022-01-15 18:09:02112#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
Zhenyao Moe9187a862017-10-20 04:26:33113bool StartSandboxLinux(gpu::GpuWatchdogThread*,
114 const gpu::GPUInfo*,
115 const gpu::GpuPreferences&);
Xiaohan Wang62737b52022-01-15 18:09:02116#elif BUILDFLAG(IS_WIN)
[email protected]663c4b32013-04-18 05:52:54117bool StartSandboxWindows(const sandbox::SandboxInterfaceInfo*);
118#endif
[email protected]ec4bda62013-06-14 15:51:03119
sadrul454af3332016-09-09 18:14:32120class ContentSandboxHelper : public gpu::GpuSandboxHelper {
121 public:
122 ContentSandboxHelper() {}
Peter Boström828b9022021-09-21 02:28:43123
124 ContentSandboxHelper(const ContentSandboxHelper&) = delete;
125 ContentSandboxHelper& operator=(const ContentSandboxHelper&) = delete;
126
sadrul454af3332016-09-09 18:14:32127 ~ContentSandboxHelper() override {}
128
Xiaohan Wang62737b52022-01-15 18:09:02129#if BUILDFLAG(IS_WIN)
sadrul454af3332016-09-09 18:14:32130 void set_sandbox_info(const sandbox::SandboxInterfaceInfo* info) {
131 sandbox_info_ = info;
132 }
133#endif
134
sadrul454af3332016-09-09 18:14:32135 private:
136 // SandboxHelper:
Ted Meyer6801a072020-10-28 03:25:02137 void PreSandboxStartup(const gpu::GpuPreferences& gpu_prefs) override {
sadrul454af3332016-09-09 18:14:32138 // Warm up resources that don't need access to GPUInfo.
139 {
140 TRACE_EVENT0("gpu", "Warm up rand");
141 // Warm up the random subsystem, which needs to be done pre-sandbox on all
142 // platforms.
Avi Drissman9a3ed4e2022-01-26 14:15:37143 std::ignore = base::RandUint64();
sadrul454af3332016-09-09 18:14:32144 }
145
Alexandre Courbotc13a5972017-07-23 03:48:48146#if BUILDFLAG(USE_VAAPI)
Xiaohan Wang62737b52022-01-15 18:09:02147#if BUILDFLAG(IS_CHROMEOS)
sadrul454af3332016-09-09 18:14:32148 media::VaapiWrapper::PreSandboxInitialization();
Pilar Molina Lopezfb5103b72021-02-26 23:35:52149#else // For Linux with VA-API support.
Ted Meyer6801a072020-10-28 03:25:02150 if (!gpu_prefs.disable_accelerated_video_decode)
Ted Meyer6f266fd2020-10-23 01:54:06151 media::VaapiWrapper::PreSandboxInitialization();
sadrul454af3332016-09-09 18:14:32152#endif
Ted Meyer6f266fd2020-10-23 01:54:06153#endif // BUILDFLAG(USE_VAAPI)
Xiaohan Wang62737b52022-01-15 18:09:02154#if BUILDFLAG(IS_WIN)
sadrul454af3332016-09-09 18:14:32155 media::DXVAVideoDecodeAccelerator::PreSandboxInitialization();
156 media::MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization();
157#endif
Eric Karle35050e2017-09-07 01:44:35158
Xiaohan Wang62737b52022-01-15 18:09:02159#if BUILDFLAG(IS_MAC)
Robert Sesek766439c92021-03-23 21:01:31160 {
Robert Sesek3bd6e4b32019-11-26 16:02:27161 TRACE_EVENT0("gpu", "Initialize VideoToolbox");
162 media::InitializeVideoToolbox();
163 }
164#endif
165
Eric Karle35050e2017-09-07 01:44:35166 // On Linux, reading system memory doesn't work through the GPU sandbox.
167 // This value is cached, so access it here to populate the cache.
168 base::SysInfo::AmountOfPhysicalMemory();
sadrul454af3332016-09-09 18:14:32169 }
170
Satyajit Sahu82a76e02017-09-18 14:50:14171 bool EnsureSandboxInitialized(gpu::GpuWatchdogThread* watchdog_thread,
Zhenyao Moe9187a862017-10-20 04:26:33172 const gpu::GPUInfo* gpu_info,
173 const gpu::GpuPreferences& gpu_prefs) override {
Xiaohan Wang62737b52022-01-15 18:09:02174#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
Zhenyao Moe9187a862017-10-20 04:26:33175 return StartSandboxLinux(watchdog_thread, gpu_info, gpu_prefs);
Xiaohan Wang62737b52022-01-15 18:09:02176#elif BUILDFLAG(IS_WIN)
sadrul454af3332016-09-09 18:14:32177 return StartSandboxWindows(sandbox_info_);
Xiaohan Wang62737b52022-01-15 18:09:02178#elif BUILDFLAG(IS_MAC)
Greg Kerr3480aa82018-02-01 00:53:03179 return sandbox::Seatbelt::IsSandboxed();
sadrul454af3332016-09-09 18:14:32180#else
181 return false;
182#endif
183 }
184
Xiaohan Wang62737b52022-01-15 18:09:02185#if BUILDFLAG(IS_WIN)
Keishi Hattori0e45c022021-11-27 09:25:52186 raw_ptr<const sandbox::SandboxInterfaceInfo> sandbox_info_ = nullptr;
sadrul454af3332016-09-09 18:14:32187#endif
sadrul454af3332016-09-09 18:14:32188};
189
kylechar476993472016-09-14 16:03:48190} // namespace
[email protected]ec4bda62013-06-14 15:51:03191
[email protected]c0fc0942010-01-13 00:55:37192// Main function for starting the Gpu process.
Gabriel Charettefbeeb1c2021-11-10 20:50:06193int GpuMain(MainFunctionParams parameters) {
[email protected]d13f35d2012-05-18 02:28:15194 TRACE_EVENT0("gpu", "GpuMain");
Ehsan Chiniforooshana8c8dad2017-11-03 07:23:09195 base::trace_event::TraceLog::GetInstance()->set_process_name("GPU Process");
ssidb2e3ece2015-02-09 16:02:20196 base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
[email protected]91a2aea2013-07-08 23:14:39197 kTraceEventGpuProcessSortIndex);
[email protected]d13f35d2012-05-18 02:28:15198
Gabriel Charettefbeeb1c2021-11-10 20:50:06199 const base::CommandLine& command_line = *parameters.command_line;
Zhenyao Mo910beb82017-10-25 03:23:00200
201 gpu::GpuPreferences gpu_preferences;
202 if (command_line.HasSwitch(switches::kGpuPreferences)) {
203 std::string value =
204 command_line.GetSwitchValueASCII(switches::kGpuPreferences);
Jonathan Backer16cc8fd2018-05-31 19:59:22205 bool success = gpu_preferences.FromSwitchValue(value);
Zhenyao Mo910beb82017-10-25 03:23:00206 CHECK(success);
207 }
208
kylechar60e12ed2021-03-15 15:56:03209 // Disallow sending sync IPCs from the GPU process, in particular CrGpuMain
210 // and VizCompositorThreads. Incoming sync IPCs can be received out of order
211 // when waiting on response to an outgoing sync IPC. Both viz and gpu
212 // interfaces rely on receiving messages in order so this message reordering
213 // would break things.
214 mojo::SyncCallRestrictions::DisallowSyncCall();
215
Zhenyao Mo910beb82017-10-25 03:23:00216 if (gpu_preferences.gpu_startup_dialog)
John Abd-El-Malek884291c2017-08-09 06:43:48217 WaitForDebugger("Gpu");
[email protected]6b889fb2010-03-23 20:09:49218
Sean Maherf36d8122022-08-05 02:33:35219 base::TimeTicks start_time = base::TimeTicks::Now();
[email protected]ca23992b02013-06-13 17:25:19220
Xiaohan Wang62737b52022-01-15 18:09:02221#if BUILDFLAG(IS_WIN)
Bill Carrba4cbb972022-10-10 18:24:11222 base::win::EnableHighDPISupport();
Daniel Libby1700bbe82019-01-30 22:22:36223 base::trace_event::TraceEventETWExport::EnableETWExport();
224
[email protected]52819472013-11-24 22:49:55225 // Prevent Windows from displaying a modal dialog on failures like not being
226 // able to load a DLL.
Benoit Lize7ee77d32021-03-04 17:26:14227 SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
228 SEM_NOOPENFILEERRORBOX);
Robert Liao98bb92d2017-06-15 22:20:39229
230 // COM is used by some Windows Media Foundation calls made on this thread and
231 // must be MTA so we don't have to worry about pumping messages to handle
232 // COM callbacks.
233 base::win::ScopedCOMInitializer com_initializer(
234 base::win::ScopedCOMInitializer::kMTA);
Sunny Sachanandani35c727c2019-07-09 13:12:52235
236 if (base::FeatureList::IsEnabled(features::kGpuProcessHighPriorityWin))
Sunny Sachanandani49bdbad2019-07-17 19:15:10237 ::SetPriorityClass(::GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS);
[email protected]23f46562011-09-07 01:42:39238#endif
[email protected]ec4bda62013-06-14 15:51:03239
Dale Curtis1b6becebb2020-03-30 20:13:35240 // Installs a base::LogMessageHandlerFunction which ensures messages are sent
241 // to the GpuProcessHost once the GpuServiceImpl has started.
242 viz::GpuServiceImpl::InstallPreInitializeLogHandler();
[email protected]23f46562011-09-07 01:42:39243
ericrk1d9e17f2016-11-30 01:51:28244 // We are experiencing what appear to be memory-stomp issues in the GPU
Alex Clarkef7fb8a82019-06-06 15:41:53245 // process. These issues seem to be impacting the task executor and listeners
246 // registered to it. Create the task executor on the heap to guard against
ericrk1d9e17f2016-11-30 01:51:28247 // this.
248 // TODO(ericrk): Revisit this once we assess its impact on crbug.com/662802
249 // and crbug.com/609252.
Alex Clarke636e7052019-05-30 10:49:37250 std::unique_ptr<base::SingleThreadTaskExecutor> main_thread_task_executor;
skyostil82befc52016-12-19 13:48:59251 std::unique_ptr<ui::PlatformEventSource> event_source;
skyostilb354f882016-12-13 18:42:45252 if (command_line.HasSwitch(switches::kHeadless)) {
Alex Clarke636e7052019-05-30 10:49:37253 main_thread_task_executor =
254 std::make_unique<base::SingleThreadTaskExecutor>(
Carlos Caballerodd8bf7b042019-07-30 14:14:15255 base::MessagePumpType::DEFAULT);
skyostilb354f882016-12-13 18:42:45256 } else {
Xiaohan Wang62737b52022-01-15 18:09:02257#if BUILDFLAG(IS_WIN)
Robert Liao98bb92d2017-06-15 22:20:39258 // The GpuMain thread should not be pumping Windows messages because no UI
259 // is expected to run on this thread.
Alex Clarke636e7052019-05-30 10:49:37260 main_thread_task_executor =
261 std::make_unique<base::SingleThreadTaskExecutor>(
Carlos Caballerodd8bf7b042019-07-30 14:14:15262 base::MessagePumpType::DEFAULT);
Maksim Sisov2ac2c312021-11-03 08:00:12263#elif defined(USE_OZONE)
Alex Clarke636e7052019-05-30 10:49:37264 // The MessagePump type required depends on the Ozone platform selected at
tonikitoofb807b102017-02-08 19:52:03265 // runtime.
Maksim Sisov459eada2020-06-25 08:16:31266 if (!main_thread_task_executor) {
267 main_thread_task_executor =
268 std::make_unique<base::SingleThreadTaskExecutor>(
269 gpu_preferences.message_pump_type);
270 }
Xiaohan Wang62737b52022-01-15 18:09:02271#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
kylechar476993472016-09-14 16:03:48272#error "Unsupported Linux platform."
Xiaohan Wang62737b52022-01-15 18:09:02273#elif BUILDFLAG(IS_MAC)
Christopher Cameron1732f2b02017-11-17 10:56:50274 // Cross-process CoreAnimation requires a CFRunLoop to function at all, and
275 // requires a NSRunLoop to not starve under heavy load. See:
276 // https://crbug.com/312462#c51 and https://crbug.com/783298
Alex Clarke636e7052019-05-30 10:49:37277 main_thread_task_executor =
278 std::make_unique<base::SingleThreadTaskExecutor>(
Carlos Caballerodd8bf7b042019-07-30 14:14:15279 base::MessagePumpType::NS_RUNLOOP);
Etienne Pierre-doray2163f3012020-04-02 21:37:14280 // As part of the migration to DoWork(), this policy is required to keep
Etienne Pierre-doray9eb4f5a2020-01-15 16:29:24281 // previous behavior and avoid regressions.
282 // TODO(crbug.com/1041853): Consider updating the policy.
283 main_thread_task_executor->SetWorkBatchSize(2);
[email protected]826aab02014-05-14 02:58:59284#else
Alex Clarke636e7052019-05-30 10:49:37285 main_thread_task_executor =
286 std::make_unique<base::SingleThreadTaskExecutor>(
Carlos Caballerodd8bf7b042019-07-30 14:14:15287 base::MessagePumpType::DEFAULT);
[email protected]db6101db2012-10-25 15:20:08288#endif
skyostilb354f882016-12-13 18:42:45289 }
[email protected]db6101db2012-10-25 15:20:08290
[email protected]db6101db2012-10-25 15:20:08291 base::PlatformThread::SetName("CrGpuMain");
292
Le Hoang Quyend6ceade62022-05-20 07:13:10293 // Set thread priority before sandbox initialization.
Zhibo Wangd9e4a002022-07-07 04:34:59294 if (!features::IsGpuMainThreadForcedToNormalPriorityDrDc()) {
295 base::PlatformThread::SetCurrentThreadType(base::ThreadType::kCompositing);
Sunny Sachanandani5cd10e962019-06-13 22:55:32296 }
revemane7acf842016-02-05 08:24:32297
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57298 auto gpu_init = std::make_unique<gpu::GpuInit>();
sadrul454af3332016-09-09 18:14:32299 ContentSandboxHelper sandbox_helper;
Xiaohan Wang62737b52022-01-15 18:09:02300#if BUILDFLAG(IS_WIN)
sadrul454af3332016-09-09 18:14:32301 sandbox_helper.set_sandbox_info(parameters.sandbox_info);
[email protected]af7c5d92014-02-03 19:53:15302#endif
[email protected]af7c5d92014-02-03 19:53:15303
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57304 gpu_init->set_sandbox_helper(&sandbox_helper);
Sadrul Habib Chowdhuryc0a4a9b92016-08-29 21:43:24305
Gabriel Charettec7e363c62020-06-24 17:39:35306 // Since GPU initialization calls into skia, it's important to initialize skia
Khushal1d055592018-07-28 02:00:39307 // before it.
308 InitializeSkia();
309
Joe Mason94bebf12022-06-03 15:03:53310 // The ThreadPool must have been created before invoking |gpu_init| as it
311 // needs the ThreadPool (in angle::InitializePlatform()). Do not start it
312 // until after the sandbox is initialized however to avoid creating threads
313 // outside the sandbox.
314 DCHECK(base::ThreadPoolInstance::Get());
Gabriel Charettec7e363c62020-06-24 17:39:35315
sadrul454af3332016-09-09 18:14:32316 // Gpu initialization may fail for various reasons, in which case we will need
317 // to tear down this process. However, we can not do so safely until the IPC
318 // channel is set up, because the detection of early return of a child process
319 // is implemented using an IPC channel error. If the IPC channel is not fully
320 // set up between the browser and GPU process, and the GPU process crashes or
321 // exits early, the browser process will never detect it. For this reason we
sadrul72aae8a2017-01-24 04:52:32322 // defer tearing down the GPU process until receiving the initialization
Sadrul Habib Chowdhury55fc2f02017-10-27 02:40:06323 // message from the browser (through mojom::VizMain::CreateGpuService()).
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57324 const bool init_success = gpu_init->InitializeAndStartSandbox(
Zhenyao Moe23f75262018-02-07 02:15:00325 const_cast<base::CommandLine*>(&command_line), gpu_preferences);
sadrul454af3332016-09-09 18:14:32326 const bool dead_on_arrival = !init_success;
Sadrul Habib Chowdhuryc0a4a9b92016-08-29 21:43:24327
Ian Barkley-Yeung48418c12022-08-16 01:10:16328 auto* client = GetContentClient()->gpu();
329 if (client) {
330 client->PostSandboxInitialized();
331 }
332
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57333 GetContentClient()->SetGpuInfo(gpu_init->gpu_info());
[email protected]ec4bda62013-06-14 15:51:03334
Zhibo Wangd9e4a002022-07-07 04:34:59335 base::ThreadType io_thread_type = base::ThreadType::kCompositing;
Xiaohan Wang62737b52022-01-15 18:09:02336#if BUILDFLAG(IS_MAC)
behdad8b57eaad2019-07-18 13:58:48337 // Increase the thread priority to get more reliable values in performance
338 // test of mac_os.
Joe Mason94bebf12022-06-03 15:03:53339 if (command_line.HasSwitch(switches::kUseHighGPUThreadPriorityForPerfTests))
Zhibo Wangd9e4a002022-07-07 04:34:59340 io_thread_type = base::ThreadType::kRealtimeAudio;
behdad8b57eaad2019-07-18 13:58:48341#endif
Joe Mason94bebf12022-06-03 15:03:53342 // ChildProcess will start the ThreadPoolInstance now that the sandbox is
343 // initialized.
Zhibo Wangd9e4a002022-07-07 04:34:59344 ChildProcess gpu_process(io_thread_type);
Joe Mason94bebf12022-06-03 15:03:53345 DCHECK(base::ThreadPoolInstance::Get()->WasStarted());
Xi Chengd6390812018-01-24 00:01:50346
Ian Barkley-Yeung48418c12022-08-16 01:10:16347 if (client) {
Xi Chengd6390812018-01-24 00:01:50348 client->PostIOThreadCreated(gpu_process.io_task_runner());
Ian Barkley-Yeung48418c12022-08-16 01:10:16349 }
Xi Chengd6390812018-01-24 00:01:50350
Wez6979109b2018-09-07 17:30:56351 base::RunLoop run_loop;
352 GpuChildThread* child_thread =
Dale Curtis1b6becebb2020-03-30 20:13:35353 new GpuChildThread(run_loop.QuitClosure(), std::move(gpu_init));
[email protected]7a31f7c2011-03-21 23:22:04354 child_thread->Init(start_time);
[email protected]995a7f12011-02-11 23:07:17355
[email protected]7a31f7c2011-03-21 23:22:04356 gpu_process.set_main_thread(child_thread);
[email protected]983c33d2010-11-16 22:38:44357
Xiaohan Wang62737b52022-01-15 18:09:02358#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_MAC)
Dale Curtis12cfe022020-02-21 01:18:42359 // Startup tracing is usually enabled earlier, but if we forked from a zygote,
360 // we can only enable it after mojo IPC support is brought up initialized by
361 // GpuChildThread, because the mojo broker has to create the tracing SMB on
362 // our behalf due to the zygote sandbox.
363 if (parameters.zygote_child)
364 tracing::EnableStartupTracingIfNeeded();
Xiaohan Wang62737b52022-01-15 18:09:02365#endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_MAC)
Dale Curtis12cfe022020-02-21 01:18:42366
Xiaohan Wang62737b52022-01-15 18:09:02367#if BUILDFLAG(IS_MAC)
Kai Ninomiyae2c55582019-12-19 23:51:03368 // A GPUEjectPolicy of 'wait' is set in the Info.plist of the browser
369 // process, meaning it is "responsible" for making sure it and its
370 // subordinate processes (i.e. the GPU process) drop references to the
371 // external GPU. Despite this, the system still sends the device removal
372 // notifications to the GPU process, so the GPU process handles its own
373 // graceful shutdown without help from the browser process.
374 //
375 // Using the "SafeEjectGPU" tool, we can see that when the browser process
376 // has a policy of 'wait', the GPU process gets the 'rwait' policy: "Eject
377 // actions apply to the responsible process, who in turn deals with
378 // subordinates to eliminate their ejecting eGPU references" [man 8
379 // SafeEjectGPU]. Empirically, the browser does not relaunch. Once the GPU
380 // process exits, it appears that the browser process is no longer considered
381 // to be using the GPU, so it "succeeds" the 'wait'.
382 metal::RegisterGracefulExitOnDeviceRemoval();
Christopher Cameron21c4abc2019-11-15 04:06:15383#endif
384
Xiaohan Wang62737b52022-01-15 18:09:02385#if BUILDFLAG(IS_ANDROID)
primianob3fb6412015-10-14 16:03:51386 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
primiano186d6bfe2015-10-30 13:21:40387 tracing::GraphicsMemoryDumpProvider::GetInstance(), "AndroidGraphics",
388 nullptr);
primianob3fb6412015-10-14 16:03:51389#endif
390
Benoit Lize7ee77d32021-03-04 17:26:14391 internal::PartitionAllocSupport::Get()->ReconfigureAfterTaskRunnerInit(
392 switches::kGpuProcess);
393
stanisc61507092017-07-06 16:36:58394 base::HighResolutionTimerManager hi_res_timer_manager;
395
[email protected]d13f35d2012-05-18 02:28:15396 {
397 TRACE_EVENT0("gpu", "Run Message Loop");
Wez6979109b2018-09-07 17:30:56398 run_loop.Run();
[email protected]d13f35d2012-05-18 02:28:15399 }
[email protected]c0fc0942010-01-13 00:55:37400
jbaumana19f1df2017-01-18 03:01:17401 return dead_on_arrival ? RESULT_CODE_GPU_DEAD_ON_ARRIVAL : 0;
[email protected]c0fc0942010-01-13 00:55:37402}
[email protected]6ec3a572012-08-17 02:09:51403
404namespace {
405
Xiaohan Wang62737b52022-01-15 18:09:02406#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
Satyajit Sahu82a76e02017-09-18 14:50:14407bool StartSandboxLinux(gpu::GpuWatchdogThread* watchdog_thread,
Zhenyao Moe9187a862017-10-20 04:26:33408 const gpu::GPUInfo* gpu_info,
409 const gpu::GpuPreferences& gpu_prefs) {
fdorayf30bf3a2015-10-28 21:47:00410 TRACE_EVENT0("gpu,startup", "Initialize sandbox");
[email protected]663c4b32013-04-18 05:52:54411
[email protected]f330b762014-02-08 04:52:46412 if (watchdog_thread) {
Tom Sepez437e2202017-10-24 21:26:47413 // SandboxLinux needs to be able to ensure that the thread
[email protected]f330b762014-02-08 04:52:46414 // has really been stopped.
Robert Sesek7d0b49b2020-07-08 18:31:27415 sandbox::policy::SandboxLinux::GetInstance()->StopThread(watchdog_thread);
[email protected]f330b762014-02-08 04:52:46416 }
[email protected]655abd522014-06-02 15:23:43417
Tom Sepez437e2202017-10-24 21:26:47418 // SandboxLinux::InitializeSandbox() must always be called
[email protected]663c4b32013-04-18 05:52:54419 // with only one thread.
Robert Sesek7d0b49b2020-07-08 18:31:27420 sandbox::policy::SandboxLinux::Options sandbox_options;
Dominik Behr1ce8bff2022-07-13 00:54:11421 if (gpu_info) {
422 // We have to enable sandbox settings for all GPUs in the system
423 // for Chrome to be able to access/use them.
424 sandbox_options.use_amd_specific_policies =
425 angle::IsAMD(gpu_info->active_gpu().vendor_id);
426 sandbox_options.use_intel_specific_policies =
427 angle::IsIntel(gpu_info->active_gpu().vendor_id);
428 sandbox_options.use_nvidia_specific_policies =
429 angle::IsNVIDIA(gpu_info->active_gpu().vendor_id);
430 for (const auto& gpu : gpu_info->secondary_gpus) {
431 if (angle::IsAMD(gpu.vendor_id))
432 sandbox_options.use_amd_specific_policies = true;
433 else if (angle::IsIntel(gpu.vendor_id))
434 sandbox_options.use_intel_specific_policies = true;
435 else if (angle::IsNVIDIA(gpu.vendor_id))
436 sandbox_options.use_nvidia_specific_policies = true;
437 }
438 }
Zhenyao Moe9187a862017-10-20 04:26:33439 sandbox_options.accelerated_video_decode_enabled =
440 !gpu_prefs.disable_accelerated_video_decode;
Sheng-Hao Tsaoea6aa852018-01-03 06:48:16441 sandbox_options.accelerated_video_encode_enabled =
442 !gpu_prefs.disable_accelerated_video_encode;
Tom Sepez085507ab2017-10-18 22:36:00443
Jeff Chenfce90f32022-01-31 19:49:34444#if BUILDFLAG(IS_CHROMEOS) && BUILDFLAG(USE_VAAPI)
445 // Increase the FD limit by 512 on VA-API Chrome OS devices in order to
446 // avoid running out of FDs in cases where many decoders are running
447 // concurrently. See b/215553848.
448 // TODO(b/195769334): revisit the need for this once out-of-process video
449 // decoding has been fully implemented.
450 const auto current_max_fds =
451 base::saturated_cast<unsigned int>(base::GetMaxFds());
452 constexpr unsigned int kMaxFDsDelta = 1u << 9;
453 const auto new_max_fds =
454 static_cast<int>(base::ClampAdd(current_max_fds, kMaxFDsDelta));
455 base::IncreaseFdLimitTo(base::checked_cast<unsigned int>(new_max_fds));
456#endif
457
Robert Sesek7d0b49b2020-07-08 18:31:27458 bool res = sandbox::policy::SandboxLinux::GetInstance()->InitializeSandbox(
459 sandbox::policy::SandboxTypeFromCommandLine(
Tom Sepez2255db72017-10-26 18:50:09460 *base::CommandLine::ForCurrentProcess()),
Tom Sepez4b101712017-11-08 19:39:58461 base::BindOnce(GpuProcessPreSandboxHook), sandbox_options);
Tom Sepeza0950c62017-10-18 20:39:14462
[email protected]f330b762014-02-08 04:52:46463 if (watchdog_thread) {
Tom Sepeza0950c62017-10-18 20:39:14464 base::Thread::Options thread_options;
465 thread_options.timer_slack = base::TIMER_SLACK_MAXIMUM;
Olivier Lia3c71552021-05-12 17:05:52466 watchdog_thread->StartWithOptions(std::move(thread_options));
[email protected]f330b762014-02-08 04:52:46467 }
[email protected]663c4b32013-04-18 05:52:54468
469 return res;
470}
Xiaohan Wang62737b52022-01-15 18:09:02471#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
[email protected]663c4b32013-04-18 05:52:54472
Xiaohan Wang62737b52022-01-15 18:09:02473#if BUILDFLAG(IS_WIN)
[email protected]663c4b32013-04-18 05:52:54474bool StartSandboxWindows(const sandbox::SandboxInterfaceInfo* sandbox_info) {
fdorayf30bf3a2015-10-28 21:47:00475 TRACE_EVENT0("gpu,startup", "Lower token");
[email protected]663c4b32013-04-18 05:52:54476
477 // For Windows, if the target_services interface is not zero, the process
478 // is sandboxed and we must call LowerToken() before rendering untrusted
479 // content.
480 sandbox::TargetServices* target_services = sandbox_info->target_services;
481 if (target_services) {
482 target_services->LowerToken();
483 return true;
484 }
485
486 return false;
487}
Xiaohan Wang62737b52022-01-15 18:09:02488#endif // BUILDFLAG(IS_WIN)
[email protected]663c4b32013-04-18 05:52:54489
[email protected]6ec3a572012-08-17 02:09:51490} // namespace.
491
[email protected]eb398192012-10-22 20:16:19492} // namespace content