blob: f4a16ca6d7fcde6f6976fc1dcb40ded428a14f25 [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>(
Patrick Monette9cfd10c2025-10-10 14:01:02177 FROM_HERE, base::MemoryPressureListenerTag::kGpuChildThread, this);
Jiahe Zhang26d66762025-09-15 06:35:39178 if (sequence_manager &&
179 base::FeatureList::IsEnabled(
180 features::kBoostThreadsPriorityDuringInputScenario)) {
181 sequence_manager->AddTaskObserver(this);
182 }
asvitkine5dc812a2016-06-07 18:20:30183}
184
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15185bool GpuChildThread::in_process_gpu() const {
Sadrul Habib Chowdhury55fc2f02017-10-27 02:40:06186 return viz_main_.gpu_service()->gpu_info().in_process_gpu;
sadrul6c5aed8c2017-01-11 23:11:44187}
188
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15189void GpuChildThread::OnInitializationFailed() {
190 OnChannelError();
191}
[email protected]96659732012-08-24 01:55:17192
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15193void GpuChildThread::OnGpuServiceConnection(viz::GpuServiceImpl* gpu_service) {
Chris Watkins88a40002017-09-28 01:16:42194 media::AndroidOverlayMojoFactoryCB overlay_factory_cb;
Xiaohan Wang62737b52022-01-15 18:09:02195#if BUILDFLAG(IS_ANDROID)
kylechared18a482019-02-07 14:07:21196 overlay_factory_cb =
197 base::BindRepeating(&GpuChildThread::CreateAndroidOverlay,
Sean Maher5b9af51f2022-11-21 15:32:47198 base::SingleThreadTaskRunner::GetCurrentDefault());
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15199 gpu_service->media_gpu_channel_manager()->SetOverlayFactory(
Chris Watkins88a40002017-09-28 01:16:42200 overlay_factory_cb);
201#endif
202
Oksana Zhuravlova04651182021-03-02 20:52:20203 if (!IsInBrowserProcess()) {
204 gpu_service->SetVisibilityChangedCallback(
205 base::BindRepeating([](bool visible) {
206 ProcessVisibilityTracker::GetInstance()->OnProcessVisibilityChanged(
207 visible);
208 }));
209 }
210
piman223a53c2016-07-21 03:41:52211 // Only set once per process instance.
Peter Boströmdd7e40ec2021-04-05 20:40:10212 service_factory_ = std::make_unique<GpuServiceFactory>(
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15213 gpu_service->gpu_preferences(),
Dan Sanders0134bec2018-04-17 20:12:12214 gpu_service->gpu_channel_manager()->gpu_driver_bug_workarounds(),
Ted Meyer68b35b92021-11-20 02:35:23215 gpu_service->gpu_feature_info(), gpu_service->gpu_info(),
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15216 gpu_service->media_gpu_channel_manager()->AsWeakPtr(),
Colin Blundellda717302025-07-08 17:10:52217 std::move(overlay_factory_cb));
Ken Rockota2924172019-12-18 03:27:05218 for (auto& receiver : pending_service_receivers_)
219 BindServiceInterface(std::move(receiver));
220 pending_service_receivers_.clear();
liberato441ca702017-05-13 16:50:38221
Ken Rockot6d9ed95032019-11-13 17:20:47222 if (GetContentClient()->gpu()) // Null in tests.
223 GetContentClient()->gpu()->GpuServiceInitialized();
piman223a53c2016-07-21 03:41:52224
Ken Rockot6d9ed95032019-11-13 17:20:47225 // Start allowing browser-exposed interfaces to be bound.
226 //
227 // NOTE: Do not add new binders within this method. Instead modify
228 // |ExposeGpuInterfacesToBrowser()| in browser_exposed_gpu_interfaces.cc, as
229 // that will ensure security review coverage.
230 mojo::BinderMap binders;
Chunbo Huad90bffb22020-09-28 15:34:36231 content::ExposeGpuInterfacesToBrowser(
Colin Blundell8b1809e2025-07-09 08:01:11232 gpu_service, gpu_service->gpu_preferences(),
Chunbo Huad90bffb22020-09-28 15:34:36233 gpu_service->gpu_channel_manager()->gpu_driver_bug_workarounds(),
234 &binders);
Ken Rockot6d9ed95032019-11-13 17:20:47235 ExposeInterfacesToBrowser(std::move(binders));
[email protected]7709e712011-01-07 17:57:31236}
237
Sadrul Habib Chowdhury97c6f1f2018-03-02 01:21:16238void GpuChildThread::PostCompositorThreadCreated(
239 base::SingleThreadTaskRunner* task_runner) {
240 auto* gpu_client = GetContentClient()->gpu();
241 if (gpu_client)
242 gpu_client->PostCompositorThreadCreated(task_runner);
243}
244
Wez6979109b2018-09-07 17:30:56245void GpuChildThread::QuitMainMessageLoop() {
Eric Karl23af711f2018-11-02 20:47:34246 quit_closure_.Run();
Wez6979109b2018-09-07 17:30:56247}
248
Jiahe Zhang26d66762025-09-15 06:35:39249void GpuChildThread::WillProcessTask(const base::PendingTask& pending_task,
250 bool was_blocked_or_low_priority) {
251 performance_scenarios::InputScenario input_scenario =
252 performance_scenarios::GetInputScenario(
253 performance_scenarios::ScenarioScope::kGlobal)
254 ->load(std::memory_order_relaxed);
255
256 // Post a task to the IO thread if the input scenario has changed. This is
257 // used to make sure the IO thread checks the scenarios in time.
258 if (input_scenario != last_input_scenario_) {
259 last_input_scenario_ = input_scenario;
260 ChildProcess::current()->io_task_runner()->PostTask(FROM_HERE,
261 base::DoNothing());
262 }
263}
264
Patrick Monette845ec832025-10-07 18:23:23265void GpuChildThread::OnMemoryPressure(base::MemoryPressureLevel level) {
266 if (level != base::MEMORY_PRESSURE_LEVEL_CRITICAL) {
Takashi Sakamotobb074802018-10-15 07:35:27267 return;
Patrick Monette845ec832025-10-07 18:23:23268 }
Khushal0aac62072018-06-01 19:33:17269
Khushal0aac62072018-06-01 19:33:17270 if (viz_main_.discardable_shared_memory_manager())
271 viz_main_.discardable_shared_memory_manager()->ReleaseFreeMemory();
272 SkGraphics::PurgeAllCaches();
273}
274
Eric Karl23af711f2018-11-02 20:47:34275void GpuChildThread::QuitSafelyHelper(
276 scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
277 // Post a new task (even if we're called on the |task_runner|'s thread) to
278 // ensure that we are post-init.
279 task_runner->PostTask(
280 FROM_HERE, base::BindOnce([]() {
281 ChildThreadImpl* current_child_thread = ChildThreadImpl::current();
282 if (!current_child_thread)
283 return;
284 GpuChildThread* gpu_child_thread =
285 static_cast<GpuChildThread*>(current_child_thread);
Patrick Todf5911c2020-05-12 19:31:42286 gpu_child_thread->viz_main_.ExitProcess(
287 viz::ExitCode::RESULT_CODE_NORMAL_EXIT);
Eric Karl23af711f2018-11-02 20:47:34288 }));
289}
290
291// Returns a closure which calls into the VizMainImpl to perform shutdown
292// before quitting the main message loop. Must be called on the main thread.
293base::RepeatingClosure GpuChildThread::MakeQuitSafelyClosure() {
294 return base::BindRepeating(&GpuChildThread::QuitSafelyHelper,
Sean Maher5b9af51f2022-11-21 15:32:47295 base::SingleThreadTaskRunner::GetCurrentDefault());
Eric Karl23af711f2018-11-02 20:47:34296}
297
Xiaohan Wang62737b52022-01-15 18:09:02298#if BUILDFLAG(IS_ANDROID)
liberato441ca702017-05-13 16:50:38299// static
300std::unique_ptr<media::AndroidOverlay> GpuChildThread::CreateAndroidOverlay(
Chris Watkins88a40002017-09-28 01:16:42301 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
liberato441ca702017-05-13 16:50:38302 const base::UnguessableToken& routing_token,
303 media::AndroidOverlayConfig config) {
Miyoung Shin18de6bf2019-10-17 07:06:24304 mojo::PendingRemote<media::mojom::AndroidOverlayProvider> overlay_provider;
Chris Watkins88a40002017-09-28 01:16:42305 if (main_task_runner->RunsTasksInCurrentSequence()) {
Miyoung Shin18de6bf2019-10-17 07:06:24306 ChildThread::Get()->BindHostReceiver(
307 overlay_provider.InitWithNewPipeAndPassReceiver());
Chris Watkins88a40002017-09-28 01:16:42308 } else {
Chris Watkins88a40002017-09-28 01:16:42309 main_task_runner->PostTask(
Ken Rockot47c47d862019-09-26 17:38:07310 FROM_HERE,
311 base::BindOnce(
Miyoung Shin18de6bf2019-10-17 07:06:24312 [](mojo::PendingReceiver<media::mojom::AndroidOverlayProvider>
313 receiver) {
314 ChildThread::Get()->BindHostReceiver(std::move(receiver));
Ken Rockot47c47d862019-09-26 17:38:07315 },
Miyoung Shin18de6bf2019-10-17 07:06:24316 overlay_provider.InitWithNewPipeAndPassReceiver()));
Chris Watkins88a40002017-09-28 01:16:42317 }
318
Jeremy Roman04f27c372017-10-27 15:20:55319 return std::make_unique<media::MojoAndroidOverlay>(
[email protected]9a635ee2017-12-01 21:38:50320 std::move(overlay_provider), std::move(config), routing_token);
liberato441ca702017-05-13 16:50:38321}
322#endif
323
[email protected]eb398192012-10-22 20:16:19324} // namespace content