blob: c9a8769e3adffcdeb9d15e555f194f8c76776f68 [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
[email protected]7a31f7c2011-03-21 23:22:045#include "content/gpu/gpu_child_thread.h"
[email protected]c0fc0942010-01-13 00:55:376
avi66a07722015-12-25 23:38:127#include <stddef.h>
Peter Boströmdd7e40ec2021-04-05 20:40:108
9#include <memory>
dchengf63a1252015-12-26 20:43:1310#include <utility>
avi66a07722015-12-25 23:38:1211
kylechar150e09e12017-10-19 13:57:5212#include "base/command_line.h"
kylechar4664a162020-09-15 03:19:3413#include "base/debug/dump_without_crashing.h"
Avi Drissmanadac21992023-01-11 23:46:3914#include "base/functional/bind.h"
15#include "base/functional/callback_helpers.h"
bend6234442017-04-24 22:51:1316#include "base/memory/weak_ptr.h"
Tom McKee14679152020-01-20 16:06:5217#include "base/power_monitor/power_monitor.h"
18#include "base/power_monitor/power_monitor_device_source.h"
Gabriel Charette53a9ef812017-07-26 12:36:2319#include "base/run_loop.h"
Jiahe Zhang26d66762025-09-15 06:35:3920#include "base/task/sequence_manager/sequence_manager.h"
Patrick Monette643cdf62021-10-15 19:13:4221#include "base/task/sequenced_task_runner.h"
Sean Maher5b9af51f2022-11-21 15:32:4722#include "base/task/single_thread_task_runner.h"
bend6234442017-04-24 22:51:1323#include "base/threading/thread_checker.h"
[email protected]274aa5882010-07-15 21:12:2324#include "build/build_config.h"
[email protected]10208ea2013-06-06 20:08:0325#include "content/child/child_process.h"
Oksana Zhuravlova04651182021-03-02 20:52:2026#include "content/common/process_visibility_tracker.h"
Ken Rockot6d9ed95032019-11-13 17:20:4727#include "content/gpu/browser_exposed_gpu_interfaces.h"
ben507aa812016-08-10 23:26:1928#include "content/gpu/gpu_service_factory.h"
[email protected]085170ca2012-05-17 20:27:2829#include "content/public/common/content_client.h"
Jiahe Zhang26d66762025-09-15 06:35:3930#include "content/public/common/content_features.h"
[email protected]c9e2cbbb2012-05-12 21:17:2731#include "content/public/common/content_switches.h"
kcwu08377ad2016-02-18 19:12:4232#include "content/public/gpu/content_gpu_client.h"
Bo Liu01d003e4e2023-08-16 19:46:5033#include "gpu/command_buffer/common/shm_count.h"
Dan Sanders0134bec2018-04-17 20:12:1234#include "gpu/ipc/service/gpu_channel_manager.h"
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:5735#include "gpu/ipc/service/gpu_init.h"
sadrul2fb7e152016-08-30 05:21:4536#include "gpu/ipc/service/gpu_watchdog_thread.h"
xhwangb2402d92016-10-15 07:29:3737#include "media/gpu/ipc/service/media_gpu_channel_manager.h"
Ken Rockot6d9ed95032019-11-13 17:20:4738#include "mojo/public/cpp/bindings/binder_map.h"
Miyoung Shin18de6bf2019-10-17 07:06:2439#include "mojo/public/cpp/bindings/pending_receiver.h"
40#include "mojo/public/cpp/bindings/pending_remote.h"
kylechar4664a162020-09-15 03:19:3441#include "mojo/public/cpp/bindings/scoped_message_error_crash_key.h"
42#include "mojo/public/cpp/system/functions.h"
Ken Rockot47c47d862019-09-26 17:38:0743#include "services/metrics/public/cpp/mojo_ukm_recorder.h"
44#include "services/metrics/public/mojom/ukm_interface.mojom.h"
bend6234442017-04-24 22:51:1345#include "services/service_manager/public/cpp/binder_registry.h"
Miyoung Shin2be27f52019-07-27 15:35:3946#include "services/viz/privileged/mojom/gl/gpu_service.mojom.h"
Khushal0aac62072018-06-01 19:33:1747#include "third_party/skia/include/core/SkGraphics.h"
[email protected]7709e712011-01-07 17:57:3148
Xiaohan Wang62737b52022-01-15 18:09:0249#if BUILDFLAG(IS_ANDROID)
chcunninghama4a8efb2017-03-22 16:55:0250#include "media/base/android/media_drm_bridge_client.h"
liberato441ca702017-05-13 16:50:3851#include "media/mojo/clients/mojo_android_overlay.h"
watkad8743d2016-04-27 20:27:4952#endif
53
Georg Neis18fc5142024-12-18 00:58:4154#if BUILDFLAG(IS_CHROMEOS)
Eric Sumc8607e72022-02-18 00:48:0355#include "components/services/font/public/cpp/font_loader.h" // nogncheck
56#include "components/services/font/public/mojom/font_service.mojom.h" // nogncheck
57#include "third_party/skia/include/core/SkRefCnt.h"
58#include "third_party/skia/include/ports/SkFontConfigInterface.h"
59#endif
60
Matthew Denton66b2fa52023-10-17 00:54:2261#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
62#include "content/child/sandboxed_process_thread_type_handler.h"
63#endif
64
[email protected]eb398192012-10-22 20:16:1965namespace content {
[email protected]7709e712011-01-07 17:57:3166namespace {
67
kylechar4664a162020-09-15 03:19:3468// Called when the GPU process receives a bad IPC message.
69void HandleBadMessage(const std::string& error) {
70 LOG(ERROR) << "Mojo error in GPU process: " << error;
71 mojo::debug::ScopedMessageErrorCrashKey crash_key_value(error);
72 base::debug::DumpWithoutCrashing();
73}
74
Ken Rockot2d483bc2021-06-17 22:39:0275ChildThreadImpl::Options GetOptions(
76 const InProcessChildThreadParams* in_process_params = nullptr) {
skyostilf28ccd0b2015-03-04 20:20:4677 ChildThreadImpl::Options::Builder builder;
wittman757af872016-08-16 00:13:4678 builder.ConnectToBrowser(true);
Ken Rockot6d9ed95032019-11-13 17:20:4779 builder.ExposesInterfacesToBrowser();
Ken Rockot2d483bc2021-06-17 22:39:0280 if (in_process_params)
81 builder.InBrowserProcess(*in_process_params);
skyostilf28ccd0b2015-03-04 20:20:4682 return builder.Build();
alexst6154ce772015-01-21 12:41:4183}
84
Ken Rockot47c47d862019-09-26 17:38:0785viz::VizMainImpl::ExternalDependencies CreateVizMainDependencies() {
Sadrul Habib Chowdhury55fc2f02017-10-27 02:40:0686 viz::VizMainImpl::ExternalDependencies deps;
Helmut Januschkabcf73212024-09-03 23:49:1887 if (!base::PowerMonitor::GetInstance()->IsInitialized()) {
Tom McKee14679152020-01-20 16:06:5288 deps.power_monitor_source =
89 std::make_unique<base::PowerMonitorDeviceSource>();
90 }
Colin Blundell7eb345b2024-11-05 13:20:1491
92#if BUILDFLAG(IS_ANDROID)
Peng Huange3b8c1d2019-03-05 17:21:1293 if (GetContentClient()->gpu()) {
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:1594 deps.sync_point_manager = GetContentClient()->gpu()->GetSyncPointManager();
Peng Huange3b8c1d2019-03-05 17:21:1295 deps.shared_image_manager =
96 GetContentClient()->gpu()->GetSharedImageManager();
Bo Liueca0009f2022-08-25 22:59:3297 deps.scheduler = GetContentClient()->gpu()->GetScheduler();
Bo Liua7b2ce62019-08-02 22:16:2398 deps.viz_compositor_thread_runner =
99 GetContentClient()->gpu()->GetVizCompositorThreadRunner();
Alex Mitrac246bcc2024-11-29 16:22:10100 deps.gr_context_options_provider =
101 GetContentClient()->gpu()->GetGrContextOptionsProvider();
Peng Huange3b8c1d2019-03-05 17:21:12102 }
Colin Blundell7eb345b2024-11-05 13:20:14103#endif
104
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15105 auto* process = ChildProcess::current();
106 deps.shutdown_event = process->GetShutDownEvent();
107 deps.io_thread_task_runner = process->io_task_runner();
Ken Rockot47c47d862019-09-26 17:38:07108
Aman Verma8c1c5e612023-04-03 23:33:58109 mojo::Remote<ukm::mojom::UkmRecorderFactory> factory;
110 ChildThread::Get()->BindHostReceiver(factory.BindNewPipeAndPassReceiver());
111 deps.ukm_recorder = ukm::MojoUkmRecorder::Create(*factory);
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15112 return deps;
113}
114
[email protected]e6ff5a31f2011-01-31 20:36:22115} // namespace
[email protected]9158f2f2011-01-27 21:08:57116
Wez6979109b2018-09-07 17:30:56117GpuChildThread::GpuChildThread(base::RepeatingClosure quit_closure,
Dale Curtis1b6becebb2020-03-30 20:13:35118 std::unique_ptr<gpu::GpuInit> gpu_init)
Wez6979109b2018-09-07 17:30:56119 : GpuChildThread(std::move(quit_closure),
120 GetOptions(),
Dale Curtis1b6becebb2020-03-30 20:13:35121 std::move(gpu_init)) {}
[email protected]9158f2f2011-01-27 21:08:57122
sadrul6d41b822017-04-02 03:38:50123GpuChildThread::GpuChildThread(const InProcessChildThreadParams& params,
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57124 std::unique_ptr<gpu::GpuInit> gpu_init)
Wez6979109b2018-09-07 17:30:56125 : GpuChildThread(base::DoNothing(),
Ken Rockot2d483bc2021-06-17 22:39:02126 GetOptions(&params),
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57127 std::move(gpu_init)) {}
sadrul041ca722017-03-24 22:35:35128
Wez6979109b2018-09-07 17:30:56129GpuChildThread::GpuChildThread(base::RepeatingClosure quit_closure,
Ken Rockot6d9ed95032019-11-13 17:20:47130 ChildThreadImpl::Options options,
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57131 std::unique_ptr<gpu::GpuInit> gpu_init)
Ken Rockot6d9ed95032019-11-13 17:20:47132 : ChildThreadImpl(MakeQuitSafelyClosure(), std::move(options)),
Ken Rockot47c47d862019-09-26 17:38:07133 viz_main_(this, CreateVizMainDependencies(), std::move(gpu_init)),
Jeremy Roman3bca4bf2019-07-11 03:41:25134 quit_closure_(std::move(quit_closure)) {
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15135 if (in_process_gpu()) {
sadrul041ca722017-03-24 22:35:35136 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
137 switches::kSingleProcess) ||
138 base::CommandLine::ForCurrentProcess()->HasSwitch(
139 switches::kInProcessGPU));
140 }
[email protected]7a31f7c2011-03-21 23:22:04141}
142
Ken Rockot6d9ed95032019-11-13 17:20:47143GpuChildThread::~GpuChildThread() = default;
[email protected]ce79d8512013-04-22 22:44:41144
Jiahe Zhang26d66762025-09-15 06:35:39145void GpuChildThread::Init(
146 const base::TimeTicks& process_start_time,
147 base::sequence_manager::SequenceManager* sequence_manager) {
kylechar4664a162020-09-15 03:19:34148 if (!in_process_gpu())
149 mojo::SetDefaultProcessErrorHandler(base::BindRepeating(&HandleBadMessage));
150
Sadrul Habib Chowdhury55fc2f02017-10-27 02:40:06151 viz_main_.gpu_service()->set_start_time(process_start_time);
xhwang9c8e1282015-10-10 01:54:07152
Matthew Denton66b2fa52023-10-17 00:54:22153#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
154 SandboxedProcessThreadTypeHandler::NotifyMainChildThreadCreated();
155#endif
156
xhwangded3b6e2016-05-25 05:24:51157 // When running in in-process mode, this has been set in the browser at
158 // ChromeBrowserMainPartsAndroid::PreMainMessageLoopRun().
Xiaohan Wang62737b52022-01-15 18:09:02159#if BUILDFLAG(IS_ANDROID)
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15160 if (!in_process_gpu()) {
chcunninghama4a8efb2017-03-22 16:55:02161 media::SetMediaDrmBridgeClient(
162 GetContentClient()->GetMediaDrmBridgeClient());
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57163 }
xhwangded3b6e2016-05-25 05:24:51164#endif
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15165
Georg Neis18fc5142024-12-18 00:58:41166#if BUILDFLAG(IS_CHROMEOS)
Eric Sumc8607e72022-02-18 00:48:03167 if (!in_process_gpu()) {
168 mojo::PendingRemote<font_service::mojom::FontService> font_service;
169 BindHostReceiver(font_service.InitWithNewPipeAndPassReceiver());
170 SkFontConfigInterface::SetGlobal(
171 sk_make_sp<font_service::FontLoader>(std::move(font_service)));
172 }
173#endif
174
Patrick Monettecc99f492025-10-08 20:22:00175 memory_pressure_listener_registration_ =
176 std::make_unique<base::AsyncMemoryPressureListenerRegistration>(
Anthony Vallee-Dubois5cb31fd2025-08-29 22:28:15177 FROM_HERE, base::MemoryPressureListenerTag::kGpuChildThread,
178 base::BindRepeating(&GpuChildThread::OnMemoryPressure,
179 base::Unretained(this)));
Jiahe Zhang26d66762025-09-15 06:35:39180 if (sequence_manager &&
181 base::FeatureList::IsEnabled(
182 features::kBoostThreadsPriorityDuringInputScenario)) {
183 sequence_manager->AddTaskObserver(this);
184 }
asvitkine5dc812a2016-06-07 18:20:30185}
186
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15187bool GpuChildThread::in_process_gpu() const {
Sadrul Habib Chowdhury55fc2f02017-10-27 02:40:06188 return viz_main_.gpu_service()->gpu_info().in_process_gpu;
sadrul6c5aed8c2017-01-11 23:11:44189}
190
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15191void GpuChildThread::OnInitializationFailed() {
192 OnChannelError();
193}
[email protected]96659732012-08-24 01:55:17194
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15195void GpuChildThread::OnGpuServiceConnection(viz::GpuServiceImpl* gpu_service) {
Chris Watkins88a40002017-09-28 01:16:42196 media::AndroidOverlayMojoFactoryCB overlay_factory_cb;
Xiaohan Wang62737b52022-01-15 18:09:02197#if BUILDFLAG(IS_ANDROID)
kylechared18a482019-02-07 14:07:21198 overlay_factory_cb =
199 base::BindRepeating(&GpuChildThread::CreateAndroidOverlay,
Sean Maher5b9af51f2022-11-21 15:32:47200 base::SingleThreadTaskRunner::GetCurrentDefault());
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15201 gpu_service->media_gpu_channel_manager()->SetOverlayFactory(
Chris Watkins88a40002017-09-28 01:16:42202 overlay_factory_cb);
203#endif
204
Oksana Zhuravlova04651182021-03-02 20:52:20205 if (!IsInBrowserProcess()) {
206 gpu_service->SetVisibilityChangedCallback(
207 base::BindRepeating([](bool visible) {
208 ProcessVisibilityTracker::GetInstance()->OnProcessVisibilityChanged(
209 visible);
210 }));
211 }
212
piman223a53c2016-07-21 03:41:52213 // Only set once per process instance.
Peter Boströmdd7e40ec2021-04-05 20:40:10214 service_factory_ = std::make_unique<GpuServiceFactory>(
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15215 gpu_service->gpu_preferences(),
Dan Sanders0134bec2018-04-17 20:12:12216 gpu_service->gpu_channel_manager()->gpu_driver_bug_workarounds(),
Ted Meyer68b35b92021-11-20 02:35:23217 gpu_service->gpu_feature_info(), gpu_service->gpu_info(),
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15218 gpu_service->media_gpu_channel_manager()->AsWeakPtr(),
Colin Blundellda717302025-07-08 17:10:52219 std::move(overlay_factory_cb));
Ken Rockota2924172019-12-18 03:27:05220 for (auto& receiver : pending_service_receivers_)
221 BindServiceInterface(std::move(receiver));
222 pending_service_receivers_.clear();
liberato441ca702017-05-13 16:50:38223
Ken Rockot6d9ed95032019-11-13 17:20:47224 if (GetContentClient()->gpu()) // Null in tests.
225 GetContentClient()->gpu()->GpuServiceInitialized();
piman223a53c2016-07-21 03:41:52226
Ken Rockot6d9ed95032019-11-13 17:20:47227 // Start allowing browser-exposed interfaces to be bound.
228 //
229 // NOTE: Do not add new binders within this method. Instead modify
230 // |ExposeGpuInterfacesToBrowser()| in browser_exposed_gpu_interfaces.cc, as
231 // that will ensure security review coverage.
232 mojo::BinderMap binders;
Chunbo Huad90bffb22020-09-28 15:34:36233 content::ExposeGpuInterfacesToBrowser(
Colin Blundell8b1809e2025-07-09 08:01:11234 gpu_service, gpu_service->gpu_preferences(),
Chunbo Huad90bffb22020-09-28 15:34:36235 gpu_service->gpu_channel_manager()->gpu_driver_bug_workarounds(),
236 &binders);
Ken Rockot6d9ed95032019-11-13 17:20:47237 ExposeInterfacesToBrowser(std::move(binders));
[email protected]7709e712011-01-07 17:57:31238}
239
Sadrul Habib Chowdhury97c6f1f2018-03-02 01:21:16240void GpuChildThread::PostCompositorThreadCreated(
241 base::SingleThreadTaskRunner* task_runner) {
242 auto* gpu_client = GetContentClient()->gpu();
243 if (gpu_client)
244 gpu_client->PostCompositorThreadCreated(task_runner);
245}
246
Wez6979109b2018-09-07 17:30:56247void GpuChildThread::QuitMainMessageLoop() {
Eric Karl23af711f2018-11-02 20:47:34248 quit_closure_.Run();
Wez6979109b2018-09-07 17:30:56249}
250
Jiahe Zhang26d66762025-09-15 06:35:39251void GpuChildThread::WillProcessTask(const base::PendingTask& pending_task,
252 bool was_blocked_or_low_priority) {
253 performance_scenarios::InputScenario input_scenario =
254 performance_scenarios::GetInputScenario(
255 performance_scenarios::ScenarioScope::kGlobal)
256 ->load(std::memory_order_relaxed);
257
258 // Post a task to the IO thread if the input scenario has changed. This is
259 // used to make sure the IO thread checks the scenarios in time.
260 if (input_scenario != last_input_scenario_) {
261 last_input_scenario_ = input_scenario;
262 ChildProcess::current()->io_task_runner()->PostTask(FROM_HERE,
263 base::DoNothing());
264 }
265}
266
Patrick Monette845ec832025-10-07 18:23:23267void GpuChildThread::OnMemoryPressure(base::MemoryPressureLevel level) {
268 if (level != base::MEMORY_PRESSURE_LEVEL_CRITICAL) {
Takashi Sakamotobb074802018-10-15 07:35:27269 return;
Patrick Monette845ec832025-10-07 18:23:23270 }
Khushal0aac62072018-06-01 19:33:17271
Khushal0aac62072018-06-01 19:33:17272 if (viz_main_.discardable_shared_memory_manager())
273 viz_main_.discardable_shared_memory_manager()->ReleaseFreeMemory();
274 SkGraphics::PurgeAllCaches();
275}
276
Eric Karl23af711f2018-11-02 20:47:34277void GpuChildThread::QuitSafelyHelper(
278 scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
279 // Post a new task (even if we're called on the |task_runner|'s thread) to
280 // ensure that we are post-init.
281 task_runner->PostTask(
282 FROM_HERE, base::BindOnce([]() {
283 ChildThreadImpl* current_child_thread = ChildThreadImpl::current();
284 if (!current_child_thread)
285 return;
286 GpuChildThread* gpu_child_thread =
287 static_cast<GpuChildThread*>(current_child_thread);
Patrick Todf5911c2020-05-12 19:31:42288 gpu_child_thread->viz_main_.ExitProcess(
289 viz::ExitCode::RESULT_CODE_NORMAL_EXIT);
Eric Karl23af711f2018-11-02 20:47:34290 }));
291}
292
293// Returns a closure which calls into the VizMainImpl to perform shutdown
294// before quitting the main message loop. Must be called on the main thread.
295base::RepeatingClosure GpuChildThread::MakeQuitSafelyClosure() {
296 return base::BindRepeating(&GpuChildThread::QuitSafelyHelper,
Sean Maher5b9af51f2022-11-21 15:32:47297 base::SingleThreadTaskRunner::GetCurrentDefault());
Eric Karl23af711f2018-11-02 20:47:34298}
299
Xiaohan Wang62737b52022-01-15 18:09:02300#if BUILDFLAG(IS_ANDROID)
liberato441ca702017-05-13 16:50:38301// static
302std::unique_ptr<media::AndroidOverlay> GpuChildThread::CreateAndroidOverlay(
Chris Watkins88a40002017-09-28 01:16:42303 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
liberato441ca702017-05-13 16:50:38304 const base::UnguessableToken& routing_token,
305 media::AndroidOverlayConfig config) {
Miyoung Shin18de6bf2019-10-17 07:06:24306 mojo::PendingRemote<media::mojom::AndroidOverlayProvider> overlay_provider;
Chris Watkins88a40002017-09-28 01:16:42307 if (main_task_runner->RunsTasksInCurrentSequence()) {
Miyoung Shin18de6bf2019-10-17 07:06:24308 ChildThread::Get()->BindHostReceiver(
309 overlay_provider.InitWithNewPipeAndPassReceiver());
Chris Watkins88a40002017-09-28 01:16:42310 } else {
Chris Watkins88a40002017-09-28 01:16:42311 main_task_runner->PostTask(
Ken Rockot47c47d862019-09-26 17:38:07312 FROM_HERE,
313 base::BindOnce(
Miyoung Shin18de6bf2019-10-17 07:06:24314 [](mojo::PendingReceiver<media::mojom::AndroidOverlayProvider>
315 receiver) {
316 ChildThread::Get()->BindHostReceiver(std::move(receiver));
Ken Rockot47c47d862019-09-26 17:38:07317 },
Miyoung Shin18de6bf2019-10-17 07:06:24318 overlay_provider.InitWithNewPipeAndPassReceiver()));
Chris Watkins88a40002017-09-28 01:16:42319 }
320
Jeremy Roman04f27c372017-10-27 15:20:55321 return std::make_unique<media::MojoAndroidOverlay>(
[email protected]9a635ee2017-12-01 21:38:50322 std::move(overlay_provider), std::move(config), routing_token);
liberato441ca702017-05-13 16:50:38323}
324#endif
325
[email protected]eb398192012-10-22 20:16:19326} // namespace content