blob: b3afa0e60f45a10cfe97b129996e1d9489b09a7d [file] [log] [blame]
[email protected]2e3d9e42012-02-14 03:23:381// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[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>
dchengf26eed32016-01-13 10:58:149#include <utility>
10
Sebastien Marchandf8cbfab2019-01-25 16:02:3011#include "base/bind.h"
Sunny Sachanandani5cd10e962019-06-13 22:55:3212#include "base/feature_list.h"
Carlos Caballerodd8bf7b042019-07-30 14:14:1513#include "base/message_loop/message_pump_type.h"
asvitkine8d51e9d2016-09-02 23:55:4314#include "base/metrics/histogram_macros.h"
[email protected]2436a6b2012-04-13 21:08:5115#include "base/rand_util.h"
fdoraye716a902016-07-05 16:05:4916#include "base/run_loop.h"
[email protected]d0ea4782013-06-11 04:58:2417#include "base/strings/string_number_conversions.h"
18#include "base/strings/stringprintf.h"
Sebastien Marchand75a7cdf2018-11-13 23:47:0319#include "base/system/sys_info.h"
Alex Clarke636e7052019-05-30 10:49:3720#include "base/task/single_thread_task_executor.h"
Gabriel Charette6f9509b2020-05-27 20:39:5721#include "base/task/thread_pool.h"
[email protected]ce072a72010-12-31 20:02:1622#include "base/threading/platform_thread.h"
stanisc61507092017-07-06 16:36:5823#include "base/timer/hi_res_timer_manager.h"
primiano50b7444c2015-01-28 04:17:0024#include "base/trace_event/trace_event.h"
[email protected]c0fc0942010-01-13 00:55:3725#include "build/build_config.h"
Yuta Hijikata76d5cb62020-12-09 09:51:5326#include "build/chromeos_buildflags.h"
Sadrul Habib Chowdhury55fc2f02017-10-27 02:40:0627#include "components/viz/service/main/viz_main_impl.h"
[email protected]91a2aea2013-07-08 23:14:3928#include "content/common/content_constants_internal.h"
John Abd-El-Malek884291c2017-08-09 06:43:4829#include "content/common/content_switches_internal.h"
Benoit Lize7ee77d32021-03-04 17:26:1430#include "content/common/partition_alloc_support.h"
Khushala4e236f2018-06-01 03:00:4631#include "content/common/skia_utils.h"
[email protected]7a31f7c2011-03-21 23:22:0432#include "content/gpu/gpu_child_thread.h"
[email protected]623c0bd2011-03-12 01:00:4133#include "content/gpu/gpu_process.h"
[email protected]c9e2cbbb2012-05-12 21:17:2734#include "content/public/common/content_client.h"
35#include "content/public/common/content_switches.h"
36#include "content/public/common/main_function_params.h"
jbaumana19f1df2017-01-18 03:01:1737#include "content/public/common/result_codes.h"
Zhenyao Moc76e9032018-01-19 21:15:4638#include "content/public/gpu/content_gpu_client.h"
[email protected]40c19e722013-11-05 23:51:2439#include "gpu/command_buffer/service/gpu_switches.h"
sadruled395922016-09-07 17:32:5840#include "gpu/config/gpu_driver_bug_list.h"
Sunny Sachanandani5cd10e962019-06-13 22:55:3241#include "gpu/config/gpu_finch_features.h"
[email protected]d7b5cc72013-05-23 20:05:0042#include "gpu/config/gpu_info_collector.h"
Jonathan Backer16cc8fd2018-05-31 19:59:2243#include "gpu/config/gpu_preferences.h"
tfarina15525c42015-04-28 19:04:1644#include "gpu/config/gpu_switches.h"
[email protected]40c19e722013-11-05 23:51:2445#include "gpu/config/gpu_util.h"
fsamuelc2774222016-03-24 00:27:1246#include "gpu/ipc/common/gpu_memory_buffer_support.h"
markdittmerd88b8352016-04-08 15:28:4547#include "gpu/ipc/service/gpu_config.h"
sadrul454af3332016-09-09 18:14:3248#include "gpu/ipc/service/gpu_init.h"
sadrul2fb7e152016-08-30 05:21:4549#include "gpu/ipc/service/gpu_watchdog_thread.h"
Scott Violeta35f9a42018-03-22 22:00:4450#include "media/gpu/buildflags.h"
kylechar60e12ed2021-03-15 15:56:0351#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
Dale Curtis12cfe022020-02-21 01:18:4252#include "services/tracing/public/cpp/trace_startup.h"
Tom Sepeza0950c62017-10-18 20:39:1453#include "third_party/angle/src/gpu_info_util/SystemInfo.h"
Maksim Sisov459eada2020-06-25 08:16:3154#include "ui/base/ui_base_features.h"
[email protected]c0939182014-05-24 00:09:1955#include "ui/events/platform/platform_event_source.h"
skyostilb354f882016-12-13 18:42:4556#include "ui/gfx/switches.h"
martina.kollarovaa34211d2015-06-25 11:49:0757#include "ui/gl/gl_context.h"
[email protected]db6101db2012-10-25 15:20:0858#include "ui/gl/gl_implementation.h"
[email protected]c9e2cbbb2012-05-12 21:17:2759#include "ui/gl/gl_surface.h"
60#include "ui/gl/gl_switches.h"
[email protected]1bb06b02012-09-23 19:37:2461#include "ui/gl/gpu_switching_manager.h"
kylechar5b9dec12016-05-16 15:40:5762#include "ui/gl/init/gl_factory.h"
[email protected]c0fc0942010-01-13 00:55:3763
avi66a07722015-12-25 23:38:1264#if defined(OS_WIN)
fdoraye716a902016-07-05 16:05:4965#include <dwmapi.h>
Benoit Lize7ee77d32021-03-04 17:26:1466#include <windows.h>
avi66a07722015-12-25 23:38:1267#endif
68
primianob3fb6412015-10-14 16:03:5169#if defined(OS_ANDROID)
70#include "base/trace_event/memory_dump_manager.h"
primianoccb26c62016-06-01 21:50:0271#include "components/tracing/common/graphics_memory_dump_provider_android.h"
primianob3fb6412015-10-14 16:03:5172#endif
73
[email protected]d7de57872011-12-06 23:32:4374#if defined(OS_WIN)
Daniel Libby8f7e6262019-01-08 22:35:5575#include "base/trace_event/trace_event_etw_export_win.h"
[email protected]5f7e4512012-10-01 20:51:3776#include "base/win/scoped_com_initializer.h"
kylechar5b9dec12016-05-16 15:40:5777#include "base/win/windows_version.h"
Miguel Casasd697adf32018-02-26 19:06:3178#include "media/gpu/windows/dxva_video_decode_accelerator_win.h"
79#include "media/gpu/windows/media_foundation_video_encode_accelerator_win.h"
[email protected]181491782012-07-18 00:59:1580#include "sandbox/win/src/sandbox.h"
[email protected]802a13a02010-12-02 01:48:3781#endif
82
[email protected]02ec37a2010-09-20 22:32:1683#if defined(USE_X11)
Tom Andersonb960daf2020-08-19 17:26:1784#include "ui/base/x/x11_ui_thread.h" // nogncheck
Tom Andersonff8d22e2020-01-30 03:19:1685#include "ui/base/x/x11_util.h" // nogncheck
86#include "ui/gfx/linux/gpu_memory_buffer_support_x11.h" // nogncheck
Tom Andersonff8d22e2020-01-30 03:19:1687#include "ui/gfx/x/x11_switches.h" // nogncheck
[email protected]02ec37a2010-09-20 22:32:1688#endif
89
Sean McAllisterbd181782020-08-13 21:05:5190#if defined(OS_LINUX) || defined(OS_CHROMEOS)
Tom Sepez085507ab2017-10-18 22:36:0091#include "content/gpu/gpu_sandbox_hook_linux.h"
[email protected]2436a6b2012-04-13 21:08:5192#include "content/public/common/sandbox_init.h"
Robert Sesek7d0b49b2020-07-08 18:31:2793#include "sandbox/policy/linux/sandbox_linux.h"
[email protected]2436a6b2012-04-13 21:08:5194#endif
95
Avi Drissman7c57be72020-07-29 20:09:4696#if defined(OS_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
Sean McAllisterbd181782020-08-13 21:05:51112#if defined(OS_LINUX) || defined(OS_CHROMEOS)
Zhenyao Moe9187a862017-10-20 04:26:33113bool StartSandboxLinux(gpu::GpuWatchdogThread*,
114 const gpu::GPUInfo*,
115 const gpu::GpuPreferences&);
[email protected]663c4b32013-04-18 05:52:54116#elif defined(OS_WIN)
117bool 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() {}
123 ~ContentSandboxHelper() override {}
124
125#if defined(OS_WIN)
126 void set_sandbox_info(const sandbox::SandboxInterfaceInfo* info) {
127 sandbox_info_ = info;
128 }
129#endif
130
sadrul454af3332016-09-09 18:14:32131 private:
132 // SandboxHelper:
Ted Meyer6801a072020-10-28 03:25:02133 void PreSandboxStartup(const gpu::GpuPreferences& gpu_prefs) override {
sadrul454af3332016-09-09 18:14:32134 // Warm up resources that don't need access to GPUInfo.
135 {
136 TRACE_EVENT0("gpu", "Warm up rand");
137 // Warm up the random subsystem, which needs to be done pre-sandbox on all
138 // platforms.
139 (void)base::RandUint64();
140 }
141
Alexandre Courbotc13a5972017-07-23 03:48:48142#if BUILDFLAG(USE_VAAPI)
Pilar Molina Lopezfb5103b72021-02-26 23:35:52143#if defined(OS_CHROMEOS)
sadrul454af3332016-09-09 18:14:32144 media::VaapiWrapper::PreSandboxInitialization();
Pilar Molina Lopezfb5103b72021-02-26 23:35:52145#else // For Linux with VA-API support.
Ted Meyer6801a072020-10-28 03:25:02146 if (!gpu_prefs.disable_accelerated_video_decode)
Ted Meyer6f266fd2020-10-23 01:54:06147 media::VaapiWrapper::PreSandboxInitialization();
sadrul454af3332016-09-09 18:14:32148#endif
Ted Meyer6f266fd2020-10-23 01:54:06149#endif // BUILDFLAG(USE_VAAPI)
sadrul454af3332016-09-09 18:14:32150#if defined(OS_WIN)
151 media::DXVAVideoDecodeAccelerator::PreSandboxInitialization();
152 media::MediaFoundationVideoEncodeAccelerator::PreSandboxInitialization();
153#endif
Eric Karle35050e2017-09-07 01:44:35154
Avi Drissman7c57be72020-07-29 20:09:46155#if defined(OS_MAC)
Robert Sesek766439c92021-03-23 21:01:31156 {
Robert Sesek3bd6e4b32019-11-26 16:02:27157 TRACE_EVENT0("gpu", "Initialize VideoToolbox");
158 media::InitializeVideoToolbox();
159 }
160#endif
161
Eric Karle35050e2017-09-07 01:44:35162 // On Linux, reading system memory doesn't work through the GPU sandbox.
163 // This value is cached, so access it here to populate the cache.
164 base::SysInfo::AmountOfPhysicalMemory();
sadrul454af3332016-09-09 18:14:32165 }
166
Satyajit Sahu82a76e02017-09-18 14:50:14167 bool EnsureSandboxInitialized(gpu::GpuWatchdogThread* watchdog_thread,
Zhenyao Moe9187a862017-10-20 04:26:33168 const gpu::GPUInfo* gpu_info,
169 const gpu::GpuPreferences& gpu_prefs) override {
Sean McAllisterbd181782020-08-13 21:05:51170#if defined(OS_LINUX) || defined(OS_CHROMEOS)
Zhenyao Moe9187a862017-10-20 04:26:33171 return StartSandboxLinux(watchdog_thread, gpu_info, gpu_prefs);
sadrul454af3332016-09-09 18:14:32172#elif defined(OS_WIN)
173 return StartSandboxWindows(sandbox_info_);
Avi Drissman7c57be72020-07-29 20:09:46174#elif defined(OS_MAC)
Greg Kerr3480aa82018-02-01 00:53:03175 return sandbox::Seatbelt::IsSandboxed();
sadrul454af3332016-09-09 18:14:32176#else
177 return false;
178#endif
179 }
180
181#if defined(OS_WIN)
182 const sandbox::SandboxInterfaceInfo* sandbox_info_ = nullptr;
sadrul454af3332016-09-09 18:14:32183#endif
184
185 DISALLOW_COPY_AND_ASSIGN(ContentSandboxHelper);
186};
187
Avi Drissman7c57be72020-07-29 20:09:46188#if defined(OS_MAC)
Christopher Camerond22d0152020-05-20 16:47:41189void TestShaderCallback(metal::TestShaderComponent component,
190 metal::TestShaderResult result,
191 const base::TimeDelta& callback_time) {
Christopher Cameron21c4abc2019-11-15 04:06:15192 switch (result) {
193 case metal::TestShaderResult::kNotAttempted:
194 case metal::TestShaderResult::kFailed:
195 // Don't include data if no Metal device was created (e.g, due to hardware
196 // or macOS version reasons).
197 return;
198 case metal::TestShaderResult::kTimedOut:
Christopher Cameronbd7837b42019-11-18 19:34:02199 break;
Christopher Cameron21c4abc2019-11-15 04:06:15200 case metal::TestShaderResult::kSucceeded:
Christopher Cameron21c4abc2019-11-15 04:06:15201 break;
202 }
Christopher Camerond22d0152020-05-20 16:47:41203 switch (component) {
204 case metal::TestShaderComponent::kCompile:
205 UMA_HISTOGRAM_MEDIUM_TIMES("Gpu.Metal.TestShaderCompileTime",
206 callback_time);
207 break;
208 case metal::TestShaderComponent::kLink:
209 UMA_HISTOGRAM_MEDIUM_TIMES("Gpu.Metal.TestShaderLinkTime", callback_time);
210 break;
211 }
Christopher Cameron21c4abc2019-11-15 04:06:15212}
213#endif
214
kylechar476993472016-09-14 16:03:48215} // namespace
[email protected]ec4bda62013-06-14 15:51:03216
[email protected]c0fc0942010-01-13 00:55:37217// Main function for starting the Gpu process.
[email protected]eb398192012-10-22 20:16:19218int GpuMain(const MainFunctionParams& parameters) {
[email protected]d13f35d2012-05-18 02:28:15219 TRACE_EVENT0("gpu", "GpuMain");
Ehsan Chiniforooshana8c8dad2017-11-03 07:23:09220 base::trace_event::TraceLog::GetInstance()->set_process_name("GPU Process");
ssidb2e3ece2015-02-09 16:02:20221 base::trace_event::TraceLog::GetInstance()->SetProcessSortIndex(
[email protected]91a2aea2013-07-08 23:14:39222 kTraceEventGpuProcessSortIndex);
[email protected]d13f35d2012-05-18 02:28:15223
avi83883c82014-12-23 00:08:49224 const base::CommandLine& command_line = parameters.command_line;
Zhenyao Mo910beb82017-10-25 03:23:00225
226 gpu::GpuPreferences gpu_preferences;
227 if (command_line.HasSwitch(switches::kGpuPreferences)) {
228 std::string value =
229 command_line.GetSwitchValueASCII(switches::kGpuPreferences);
Jonathan Backer16cc8fd2018-05-31 19:59:22230 bool success = gpu_preferences.FromSwitchValue(value);
Zhenyao Mo910beb82017-10-25 03:23:00231 CHECK(success);
232 }
233
kylechar60e12ed2021-03-15 15:56:03234 // Disallow sending sync IPCs from the GPU process, in particular CrGpuMain
235 // and VizCompositorThreads. Incoming sync IPCs can be received out of order
236 // when waiting on response to an outgoing sync IPC. Both viz and gpu
237 // interfaces rely on receiving messages in order so this message reordering
238 // would break things.
239 mojo::SyncCallRestrictions::DisallowSyncCall();
240
Zhenyao Mo910beb82017-10-25 03:23:00241 if (gpu_preferences.gpu_startup_dialog)
John Abd-El-Malek884291c2017-08-09 06:43:48242 WaitForDebugger("Gpu");
[email protected]6b889fb2010-03-23 20:09:49243
[email protected]ca23992b02013-06-13 17:25:19244 base::Time start_time = base::Time::Now();
245
[email protected]23f46562011-09-07 01:42:39246#if defined(OS_WIN)
Daniel Libby1700bbe82019-01-30 22:22:36247 base::trace_event::TraceEventETWExport::EnableETWExport();
248
[email protected]52819472013-11-24 22:49:55249 // Prevent Windows from displaying a modal dialog on failures like not being
250 // able to load a DLL.
Benoit Lize7ee77d32021-03-04 17:26:14251 SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
252 SEM_NOOPENFILEERRORBOX);
Robert Liao98bb92d2017-06-15 22:20:39253
254 // COM is used by some Windows Media Foundation calls made on this thread and
255 // must be MTA so we don't have to worry about pumping messages to handle
256 // COM callbacks.
257 base::win::ScopedCOMInitializer com_initializer(
258 base::win::ScopedCOMInitializer::kMTA);
Sunny Sachanandani35c727c2019-07-09 13:12:52259
260 if (base::FeatureList::IsEnabled(features::kGpuProcessHighPriorityWin))
Sunny Sachanandani49bdbad2019-07-17 19:15:10261 ::SetPriorityClass(::GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS);
[email protected]23f46562011-09-07 01:42:39262#endif
[email protected]ec4bda62013-06-14 15:51:03263
Dale Curtis1b6becebb2020-03-30 20:13:35264 // Installs a base::LogMessageHandlerFunction which ensures messages are sent
265 // to the GpuProcessHost once the GpuServiceImpl has started.
266 viz::GpuServiceImpl::InstallPreInitializeLogHandler();
[email protected]23f46562011-09-07 01:42:39267
ericrk1d9e17f2016-11-30 01:51:28268 // We are experiencing what appear to be memory-stomp issues in the GPU
Alex Clarkef7fb8a82019-06-06 15:41:53269 // process. These issues seem to be impacting the task executor and listeners
270 // registered to it. Create the task executor on the heap to guard against
ericrk1d9e17f2016-11-30 01:51:28271 // this.
272 // TODO(ericrk): Revisit this once we assess its impact on crbug.com/662802
273 // and crbug.com/609252.
Alex Clarke636e7052019-05-30 10:49:37274 std::unique_ptr<base::SingleThreadTaskExecutor> main_thread_task_executor;
skyostil82befc52016-12-19 13:48:59275 std::unique_ptr<ui::PlatformEventSource> event_source;
skyostilb354f882016-12-13 18:42:45276 if (command_line.HasSwitch(switches::kHeadless)) {
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::DEFAULT);
skyostilb354f882016-12-13 18:42:45280 } else {
[email protected]db6101db2012-10-25 15:20:08281#if defined(OS_WIN)
Robert Liao98bb92d2017-06-15 22:20:39282 // The GpuMain thread should not be pumping Windows messages because no UI
283 // is expected to run on this thread.
Alex Clarke636e7052019-05-30 10:49:37284 main_thread_task_executor =
285 std::make_unique<base::SingleThreadTaskExecutor>(
Carlos Caballerodd8bf7b042019-07-30 14:14:15286 base::MessagePumpType::DEFAULT);
Maksim Sisov459eada2020-06-25 08:16:31287#elif defined(USE_X11) || defined(USE_OZONE)
288#if defined(USE_X11)
289 if (!features::IsUsingOzonePlatform()) {
290 // We need a UI loop so that we can grab the Expose events. See
291 // GLSurfaceGLX and https://crbug.com/326995.
Tom Andersone4fc22a2020-10-28 07:14:14292 if (!x11::Connection::Get()->Ready())
Maksim Sisov459eada2020-06-25 08:16:31293 return RESULT_CODE_GPU_DEAD_ON_ARRIVAL;
294 main_thread_task_executor =
295 std::make_unique<base::SingleThreadTaskExecutor>(
296 base::MessagePumpType::UI);
297 event_source = ui::PlatformEventSource::CreateDefault();
Tom Andersonb960daf2020-08-19 17:26:17298 // Set up the X11UiThread before the sandbox gets set up. This cannot be
299 // done later since opening the connection requires socket() and
300 // connect().
301 ui::X11UiThread::SetConnection(x11::Connection::Get()->Clone().release());
Maksim Sisov459eada2020-06-25 08:16:31302 }
303#endif
304#if defined(USE_OZONE)
Alex Clarke636e7052019-05-30 10:49:37305 // The MessagePump type required depends on the Ozone platform selected at
tonikitoofb807b102017-02-08 19:52:03306 // runtime.
Maksim Sisov459eada2020-06-25 08:16:31307 if (!main_thread_task_executor) {
308 main_thread_task_executor =
309 std::make_unique<base::SingleThreadTaskExecutor>(
310 gpu_preferences.message_pump_type);
311 }
312#endif
Sean McAllisterbd181782020-08-13 21:05:51313#elif defined(OS_LINUX) || defined(OS_CHROMEOS)
kylechar476993472016-09-14 16:03:48314#error "Unsupported Linux platform."
Avi Drissman7c57be72020-07-29 20:09:46315#elif defined(OS_MAC)
Christopher Cameron1732f2b02017-11-17 10:56:50316 // Cross-process CoreAnimation requires a CFRunLoop to function at all, and
317 // requires a NSRunLoop to not starve under heavy load. See:
318 // https://crbug.com/312462#c51 and https://crbug.com/783298
Alex Clarke636e7052019-05-30 10:49:37319 main_thread_task_executor =
320 std::make_unique<base::SingleThreadTaskExecutor>(
Carlos Caballerodd8bf7b042019-07-30 14:14:15321 base::MessagePumpType::NS_RUNLOOP);
Etienne Pierre-doray2163f3012020-04-02 21:37:14322 // As part of the migration to DoWork(), this policy is required to keep
Etienne Pierre-doray9eb4f5a2020-01-15 16:29:24323 // previous behavior and avoid regressions.
324 // TODO(crbug.com/1041853): Consider updating the policy.
325 main_thread_task_executor->SetWorkBatchSize(2);
[email protected]826aab02014-05-14 02:58:59326#else
Alex Clarke636e7052019-05-30 10:49:37327 main_thread_task_executor =
328 std::make_unique<base::SingleThreadTaskExecutor>(
Carlos Caballerodd8bf7b042019-07-30 14:14:15329 base::MessagePumpType::DEFAULT);
[email protected]db6101db2012-10-25 15:20:08330#endif
skyostilb354f882016-12-13 18:42:45331 }
[email protected]db6101db2012-10-25 15:20:08332
[email protected]db6101db2012-10-25 15:20:08333 base::PlatformThread::SetName("CrGpuMain");
334
Avi Drissman7c57be72020-07-29 20:09:46335#if !defined(OS_MAC)
Sunny Sachanandani5cd10e962019-06-13 22:55:32336 if (base::FeatureList::IsEnabled(features::kGpuUseDisplayThreadPriority)) {
337 // Set thread priority before sandbox initialization.
338 base::PlatformThread::SetCurrentThreadPriority(
339 base::ThreadPriority::DISPLAY);
340 }
Michael Spang50ed1ff2019-07-02 22:26:56341#endif
revemane7acf842016-02-05 08:24:32342
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57343 auto gpu_init = std::make_unique<gpu::GpuInit>();
sadrul454af3332016-09-09 18:14:32344 ContentSandboxHelper sandbox_helper;
345#if defined(OS_WIN)
346 sandbox_helper.set_sandbox_info(parameters.sandbox_info);
[email protected]af7c5d92014-02-03 19:53:15347#endif
[email protected]af7c5d92014-02-03 19:53:15348
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57349 gpu_init->set_sandbox_helper(&sandbox_helper);
Sadrul Habib Chowdhuryc0a4a9b92016-08-29 21:43:24350
Gabriel Charettec7e363c62020-06-24 17:39:35351 // Since GPU initialization calls into skia, it's important to initialize skia
Khushal1d055592018-07-28 02:00:39352 // before it.
353 InitializeSkia();
354
Gabriel Charettec7e363c62020-06-24 17:39:35355 // Create the ThreadPool before invoking |gpu_init| as it needs the ThreadPool
356 // (in angle::InitializePlatform()). Do not start it until after the sandbox
357 // is initialized however to avoid creating threads outside the sandbox.
358 base::ThreadPoolInstance::Create("GPU");
359
sadrul454af3332016-09-09 18:14:32360 // Gpu initialization may fail for various reasons, in which case we will need
361 // to tear down this process. However, we can not do so safely until the IPC
362 // channel is set up, because the detection of early return of a child process
363 // is implemented using an IPC channel error. If the IPC channel is not fully
364 // set up between the browser and GPU process, and the GPU process crashes or
365 // exits early, the browser process will never detect it. For this reason we
sadrul72aae8a2017-01-24 04:52:32366 // defer tearing down the GPU process until receiving the initialization
Sadrul Habib Chowdhury55fc2f02017-10-27 02:40:06367 // message from the browser (through mojom::VizMain::CreateGpuService()).
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57368 const bool init_success = gpu_init->InitializeAndStartSandbox(
Zhenyao Moe23f75262018-02-07 02:15:00369 const_cast<base::CommandLine*>(&command_line), gpu_preferences);
sadrul454af3332016-09-09 18:14:32370 const bool dead_on_arrival = !init_success;
Sadrul Habib Chowdhuryc0a4a9b92016-08-29 21:43:24371
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57372 GetContentClient()->SetGpuInfo(gpu_init->gpu_info());
[email protected]ec4bda62013-06-14 15:51:03373
Gabriel Charettec7e363c62020-06-24 17:39:35374 // Start the ThreadPoolInstance now that the sandbox is initialized.
375 base::ThreadPoolInstance::Get()->StartWithDefaultParams();
376
Sunny Sachanandani5cd10e962019-06-13 22:55:32377 const base::ThreadPriority io_thread_priority =
378 base::FeatureList::IsEnabled(features::kGpuUseDisplayThreadPriority)
379 ? base::ThreadPriority::DISPLAY
380 : base::ThreadPriority::NORMAL;
Avi Drissman7c57be72020-07-29 20:09:46381#if defined(OS_MAC)
behdad8b57eaad2019-07-18 13:58:48382 // Increase the thread priority to get more reliable values in performance
383 // test of mac_os.
384 GpuProcess gpu_process(
385 (command_line.HasSwitch(switches::kUseHighGPUThreadPriorityForPerfTests)
386 ? base::ThreadPriority::REALTIME_AUDIO
387 : io_thread_priority));
388#else
reveman7caf8cf2016-02-16 02:39:05389 GpuProcess gpu_process(io_thread_priority);
behdad8b57eaad2019-07-18 13:58:48390#endif
Xi Chengd6390812018-01-24 00:01:50391
Tom Andersonff8d22e2020-01-30 03:19:16392#if defined(USE_X11)
393 // ui::GbmDevice() takes >50ms with amdgpu, so kick off
394 // GpuMemoryBufferSupportX11 creation on another thread now.
Maksim Sisove8bf9222020-06-24 07:53:02395 if (!features::IsUsingOzonePlatform() &&
396 gpu_preferences.enable_native_gpu_memory_buffers) {
Gabriel Charette6f9509b2020-05-27 20:39:57397 base::ThreadPool::PostTask(
Tom Andersonbe0638f2020-05-21 01:20:33398 FROM_HERE, base::BindOnce([]() {
399 SCOPED_UMA_HISTOGRAM_TIMER("Linux.X11.GbmSupportX11CreationTime");
400 ui::GpuMemoryBufferSupportX11::GetInstance();
401 }));
402 }
Tom Andersonff8d22e2020-01-30 03:19:16403#endif
404
Zhenyao Moe23f75262018-02-07 02:15:00405 auto* client = GetContentClient()->gpu();
Xi Chengd6390812018-01-24 00:01:50406 if (client)
407 client->PostIOThreadCreated(gpu_process.io_task_runner());
408
Wez6979109b2018-09-07 17:30:56409 base::RunLoop run_loop;
410 GpuChildThread* child_thread =
Dale Curtis1b6becebb2020-03-30 20:13:35411 new GpuChildThread(run_loop.QuitClosure(), std::move(gpu_init));
[email protected]7a31f7c2011-03-21 23:22:04412 child_thread->Init(start_time);
[email protected]995a7f12011-02-11 23:07:17413
[email protected]7a31f7c2011-03-21 23:22:04414 gpu_process.set_main_thread(child_thread);
[email protected]983c33d2010-11-16 22:38:44415
Avi Drissman7c57be72020-07-29 20:09:46416#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MAC)
Dale Curtis12cfe022020-02-21 01:18:42417 // Startup tracing is usually enabled earlier, but if we forked from a zygote,
418 // we can only enable it after mojo IPC support is brought up initialized by
419 // GpuChildThread, because the mojo broker has to create the tracing SMB on
420 // our behalf due to the zygote sandbox.
421 if (parameters.zygote_child)
422 tracing::EnableStartupTracingIfNeeded();
Avi Drissmand4d79f72020-07-30 18:35:18423#endif // OS_POSIX && !OS_ANDROID && !OS_MAC
Dale Curtis12cfe022020-02-21 01:18:42424
Avi Drissman7c57be72020-07-29 20:09:46425#if defined(OS_MAC)
Kai Ninomiyae2c55582019-12-19 23:51:03426 // A GPUEjectPolicy of 'wait' is set in the Info.plist of the browser
427 // process, meaning it is "responsible" for making sure it and its
428 // subordinate processes (i.e. the GPU process) drop references to the
429 // external GPU. Despite this, the system still sends the device removal
430 // notifications to the GPU process, so the GPU process handles its own
431 // graceful shutdown without help from the browser process.
432 //
433 // Using the "SafeEjectGPU" tool, we can see that when the browser process
434 // has a policy of 'wait', the GPU process gets the 'rwait' policy: "Eject
435 // actions apply to the responsible process, who in turn deals with
436 // subordinates to eliminate their ejecting eGPU references" [man 8
437 // SafeEjectGPU]. Empirically, the browser does not relaunch. Once the GPU
438 // process exits, it appears that the browser process is no longer considered
439 // to be using the GPU, so it "succeeds" the 'wait'.
440 metal::RegisterGracefulExitOnDeviceRemoval();
441
Christopher Cameron21c4abc2019-11-15 04:06:15442 // Launch a test metal shader compile to see how long it takes to complete (if
443 // it ever completes).
444 // https://crbug.com/974219
Christopher Camerond362a662019-11-27 17:45:18445 metal::TestShader(base::BindOnce(TestShaderCallback));
Christopher Cameron21c4abc2019-11-15 04:06:15446#endif
447
primianob3fb6412015-10-14 16:03:51448#if defined(OS_ANDROID)
449 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
primiano186d6bfe2015-10-30 13:21:40450 tracing::GraphicsMemoryDumpProvider::GetInstance(), "AndroidGraphics",
451 nullptr);
primianob3fb6412015-10-14 16:03:51452#endif
453
Benoit Lize7ee77d32021-03-04 17:26:14454 internal::PartitionAllocSupport::Get()->ReconfigureAfterTaskRunnerInit(
455 switches::kGpuProcess);
456
stanisc61507092017-07-06 16:36:58457 base::HighResolutionTimerManager hi_res_timer_manager;
458
[email protected]d13f35d2012-05-18 02:28:15459 {
460 TRACE_EVENT0("gpu", "Run Message Loop");
Wez6979109b2018-09-07 17:30:56461 run_loop.Run();
[email protected]d13f35d2012-05-18 02:28:15462 }
[email protected]c0fc0942010-01-13 00:55:37463
jbaumana19f1df2017-01-18 03:01:17464 return dead_on_arrival ? RESULT_CODE_GPU_DEAD_ON_ARRIVAL : 0;
[email protected]c0fc0942010-01-13 00:55:37465}
[email protected]6ec3a572012-08-17 02:09:51466
467namespace {
468
Sean McAllisterbd181782020-08-13 21:05:51469#if defined(OS_LINUX) || defined(OS_CHROMEOS)
Satyajit Sahu82a76e02017-09-18 14:50:14470bool StartSandboxLinux(gpu::GpuWatchdogThread* watchdog_thread,
Zhenyao Moe9187a862017-10-20 04:26:33471 const gpu::GPUInfo* gpu_info,
472 const gpu::GpuPreferences& gpu_prefs) {
fdorayf30bf3a2015-10-28 21:47:00473 TRACE_EVENT0("gpu,startup", "Initialize sandbox");
[email protected]663c4b32013-04-18 05:52:54474
[email protected]f330b762014-02-08 04:52:46475 if (watchdog_thread) {
Tom Sepez437e2202017-10-24 21:26:47476 // SandboxLinux needs to be able to ensure that the thread
[email protected]f330b762014-02-08 04:52:46477 // has really been stopped.
Robert Sesek7d0b49b2020-07-08 18:31:27478 sandbox::policy::SandboxLinux::GetInstance()->StopThread(watchdog_thread);
[email protected]f330b762014-02-08 04:52:46479 }
[email protected]655abd522014-06-02 15:23:43480
Tom Sepez437e2202017-10-24 21:26:47481 // SandboxLinux::InitializeSandbox() must always be called
[email protected]663c4b32013-04-18 05:52:54482 // with only one thread.
Robert Sesek7d0b49b2020-07-08 18:31:27483 sandbox::policy::SandboxLinux::Options sandbox_options;
Tom Sepeza0950c62017-10-18 20:39:14484 sandbox_options.use_amd_specific_policies =
485 gpu_info && angle::IsAMD(gpu_info->active_gpu().vendor_id);
Brian Hoe7c074832019-12-11 20:20:52486 sandbox_options.use_intel_specific_policies =
487 gpu_info && angle::IsIntel(gpu_info->active_gpu().vendor_id);
Tom Anderson0fd12d92020-10-31 00:55:52488 sandbox_options.use_nvidia_specific_policies =
489 gpu_info && angle::IsNVIDIA(gpu_info->active_gpu().vendor_id);
Zhenyao Moe9187a862017-10-20 04:26:33490 sandbox_options.accelerated_video_decode_enabled =
491 !gpu_prefs.disable_accelerated_video_decode;
Sheng-Hao Tsaoea6aa852018-01-03 06:48:16492 sandbox_options.accelerated_video_encode_enabled =
493 !gpu_prefs.disable_accelerated_video_encode;
Tom Sepez085507ab2017-10-18 22:36:00494
Robert Sesek7d0b49b2020-07-08 18:31:27495 bool res = sandbox::policy::SandboxLinux::GetInstance()->InitializeSandbox(
496 sandbox::policy::SandboxTypeFromCommandLine(
Tom Sepez2255db72017-10-26 18:50:09497 *base::CommandLine::ForCurrentProcess()),
Tom Sepez4b101712017-11-08 19:39:58498 base::BindOnce(GpuProcessPreSandboxHook), sandbox_options);
Tom Sepeza0950c62017-10-18 20:39:14499
[email protected]f330b762014-02-08 04:52:46500 if (watchdog_thread) {
Tom Sepeza0950c62017-10-18 20:39:14501 base::Thread::Options thread_options;
502 thread_options.timer_slack = base::TIMER_SLACK_MAXIMUM;
503 watchdog_thread->StartWithOptions(thread_options);
[email protected]f330b762014-02-08 04:52:46504 }
[email protected]663c4b32013-04-18 05:52:54505
506 return res;
507}
Sean McAllisterbd181782020-08-13 21:05:51508#endif // defined(OS_LINUX) || defined(OS_CHROMEOS)
[email protected]663c4b32013-04-18 05:52:54509
510#if defined(OS_WIN)
511bool StartSandboxWindows(const sandbox::SandboxInterfaceInfo* sandbox_info) {
fdorayf30bf3a2015-10-28 21:47:00512 TRACE_EVENT0("gpu,startup", "Lower token");
[email protected]663c4b32013-04-18 05:52:54513
514 // For Windows, if the target_services interface is not zero, the process
515 // is sandboxed and we must call LowerToken() before rendering untrusted
516 // content.
517 sandbox::TargetServices* target_services = sandbox_info->target_services;
518 if (target_services) {
519 target_services->LowerToken();
520 return true;
521 }
522
523 return false;
524}
525#endif // defined(OS_WIN)
526
[email protected]6ec3a572012-08-17 02:09:51527} // namespace.
528
[email protected]eb398192012-10-22 20:16:19529} // namespace content