blob: 7da279cf2aa595611d4c2fd6a43412f654280a46 [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"
Patrick Monette643cdf62021-10-15 19:13:4220#include "base/task/sequenced_task_runner.h"
Sean Maher5b9af51f2022-11-21 15:32:4721#include "base/task/single_thread_task_runner.h"
bend6234442017-04-24 22:51:1322#include "base/threading/thread_checker.h"
[email protected]274aa5882010-07-15 21:12:2323#include "build/build_config.h"
[email protected]10208ea2013-06-06 20:08:0324#include "content/child/child_process.h"
Oksana Zhuravlova04651182021-03-02 20:52:2025#include "content/common/process_visibility_tracker.h"
Ken Rockot6d9ed95032019-11-13 17:20:4726#include "content/gpu/browser_exposed_gpu_interfaces.h"
ben507aa812016-08-10 23:26:1927#include "content/gpu/gpu_service_factory.h"
[email protected]085170ca2012-05-17 20:27:2828#include "content/public/common/content_client.h"
[email protected]c9e2cbbb2012-05-12 21:17:2729#include "content/public/common/content_switches.h"
kcwu08377ad2016-02-18 19:12:4230#include "content/public/gpu/content_gpu_client.h"
Bo Liu01d003e4e2023-08-16 19:46:5031#include "gpu/command_buffer/common/shm_count.h"
Dan Sanders0134bec2018-04-17 20:12:1232#include "gpu/ipc/service/gpu_channel_manager.h"
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:5733#include "gpu/ipc/service/gpu_init.h"
sadrul2fb7e152016-08-30 05:21:4534#include "gpu/ipc/service/gpu_watchdog_thread.h"
xhwangb2402d92016-10-15 07:29:3735#include "media/gpu/ipc/service/media_gpu_channel_manager.h"
Ken Rockot6d9ed95032019-11-13 17:20:4736#include "mojo/public/cpp/bindings/binder_map.h"
Miyoung Shin18de6bf2019-10-17 07:06:2437#include "mojo/public/cpp/bindings/pending_receiver.h"
38#include "mojo/public/cpp/bindings/pending_remote.h"
kylechar4664a162020-09-15 03:19:3439#include "mojo/public/cpp/bindings/scoped_message_error_crash_key.h"
40#include "mojo/public/cpp/system/functions.h"
Ken Rockot47c47d862019-09-26 17:38:0741#include "services/metrics/public/cpp/mojo_ukm_recorder.h"
42#include "services/metrics/public/mojom/ukm_interface.mojom.h"
bend6234442017-04-24 22:51:1343#include "services/service_manager/public/cpp/binder_registry.h"
Miyoung Shin2be27f52019-07-27 15:35:3944#include "services/viz/privileged/mojom/gl/gpu_service.mojom.h"
Khushal0aac62072018-06-01 19:33:1745#include "third_party/skia/include/core/SkGraphics.h"
[email protected]7709e712011-01-07 17:57:3146
Xiaohan Wang62737b52022-01-15 18:09:0247#if BUILDFLAG(IS_ANDROID)
chcunninghama4a8efb2017-03-22 16:55:0248#include "media/base/android/media_drm_bridge_client.h"
liberato441ca702017-05-13 16:50:3849#include "media/mojo/clients/mojo_android_overlay.h"
watkad8743d2016-04-27 20:27:4950#endif
51
Georg Neis18fc5142024-12-18 00:58:4152#if BUILDFLAG(IS_CHROMEOS)
Eric Sumc8607e72022-02-18 00:48:0353#include "components/services/font/public/cpp/font_loader.h" // nogncheck
54#include "components/services/font/public/mojom/font_service.mojom.h" // nogncheck
55#include "third_party/skia/include/core/SkRefCnt.h"
56#include "third_party/skia/include/ports/SkFontConfigInterface.h"
57#endif
58
Matthew Denton66b2fa52023-10-17 00:54:2259#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
60#include "content/child/sandboxed_process_thread_type_handler.h"
61#endif
62
[email protected]eb398192012-10-22 20:16:1963namespace content {
[email protected]7709e712011-01-07 17:57:3164namespace {
65
kylechar4664a162020-09-15 03:19:3466// Called when the GPU process receives a bad IPC message.
67void HandleBadMessage(const std::string& error) {
68 LOG(ERROR) << "Mojo error in GPU process: " << error;
69 mojo::debug::ScopedMessageErrorCrashKey crash_key_value(error);
70 base::debug::DumpWithoutCrashing();
71}
72
Ken Rockot2d483bc2021-06-17 22:39:0273ChildThreadImpl::Options GetOptions(
74 const InProcessChildThreadParams* in_process_params = nullptr) {
skyostilf28ccd0b2015-03-04 20:20:4675 ChildThreadImpl::Options::Builder builder;
wittman757af872016-08-16 00:13:4676 builder.ConnectToBrowser(true);
Ken Rockot6d9ed95032019-11-13 17:20:4777 builder.ExposesInterfacesToBrowser();
Ken Rockot2d483bc2021-06-17 22:39:0278 if (in_process_params)
79 builder.InBrowserProcess(*in_process_params);
skyostilf28ccd0b2015-03-04 20:20:4680 return builder.Build();
alexst6154ce772015-01-21 12:41:4181}
82
Ken Rockot47c47d862019-09-26 17:38:0783viz::VizMainImpl::ExternalDependencies CreateVizMainDependencies() {
Sadrul Habib Chowdhury55fc2f02017-10-27 02:40:0684 viz::VizMainImpl::ExternalDependencies deps;
Helmut Januschkabcf73212024-09-03 23:49:1885 if (!base::PowerMonitor::GetInstance()->IsInitialized()) {
Tom McKee14679152020-01-20 16:06:5286 deps.power_monitor_source =
87 std::make_unique<base::PowerMonitorDeviceSource>();
88 }
Colin Blundell7eb345b2024-11-05 13:20:1489
90#if BUILDFLAG(IS_ANDROID)
Peng Huange3b8c1d2019-03-05 17:21:1291 if (GetContentClient()->gpu()) {
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:1592 deps.sync_point_manager = GetContentClient()->gpu()->GetSyncPointManager();
Peng Huange3b8c1d2019-03-05 17:21:1293 deps.shared_image_manager =
94 GetContentClient()->gpu()->GetSharedImageManager();
Bo Liueca0009f2022-08-25 22:59:3295 deps.scheduler = GetContentClient()->gpu()->GetScheduler();
Bo Liua7b2ce62019-08-02 22:16:2396 deps.viz_compositor_thread_runner =
97 GetContentClient()->gpu()->GetVizCompositorThreadRunner();
Alex Mitrac246bcc2024-11-29 16:22:1098 deps.gr_context_options_provider =
99 GetContentClient()->gpu()->GetGrContextOptionsProvider();
Peng Huange3b8c1d2019-03-05 17:21:12100 }
Colin Blundell7eb345b2024-11-05 13:20:14101#endif
102
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15103 auto* process = ChildProcess::current();
104 deps.shutdown_event = process->GetShutDownEvent();
105 deps.io_thread_task_runner = process->io_task_runner();
Ken Rockot47c47d862019-09-26 17:38:07106
Aman Verma8c1c5e612023-04-03 23:33:58107 mojo::Remote<ukm::mojom::UkmRecorderFactory> factory;
108 ChildThread::Get()->BindHostReceiver(factory.BindNewPipeAndPassReceiver());
109 deps.ukm_recorder = ukm::MojoUkmRecorder::Create(*factory);
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15110 return deps;
111}
112
[email protected]e6ff5a31f2011-01-31 20:36:22113} // namespace
[email protected]9158f2f2011-01-27 21:08:57114
Wez6979109b2018-09-07 17:30:56115GpuChildThread::GpuChildThread(base::RepeatingClosure quit_closure,
Dale Curtis1b6becebb2020-03-30 20:13:35116 std::unique_ptr<gpu::GpuInit> gpu_init)
Wez6979109b2018-09-07 17:30:56117 : GpuChildThread(std::move(quit_closure),
118 GetOptions(),
Dale Curtis1b6becebb2020-03-30 20:13:35119 std::move(gpu_init)) {}
[email protected]9158f2f2011-01-27 21:08:57120
sadrul6d41b822017-04-02 03:38:50121GpuChildThread::GpuChildThread(const InProcessChildThreadParams& params,
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57122 std::unique_ptr<gpu::GpuInit> gpu_init)
Wez6979109b2018-09-07 17:30:56123 : GpuChildThread(base::DoNothing(),
Ken Rockot2d483bc2021-06-17 22:39:02124 GetOptions(&params),
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57125 std::move(gpu_init)) {}
sadrul041ca722017-03-24 22:35:35126
Wez6979109b2018-09-07 17:30:56127GpuChildThread::GpuChildThread(base::RepeatingClosure quit_closure,
Ken Rockot6d9ed95032019-11-13 17:20:47128 ChildThreadImpl::Options options,
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57129 std::unique_ptr<gpu::GpuInit> gpu_init)
Ken Rockot6d9ed95032019-11-13 17:20:47130 : ChildThreadImpl(MakeQuitSafelyClosure(), std::move(options)),
Ken Rockot47c47d862019-09-26 17:38:07131 viz_main_(this, CreateVizMainDependencies(), std::move(gpu_init)),
Jeremy Roman3bca4bf2019-07-11 03:41:25132 quit_closure_(std::move(quit_closure)) {
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15133 if (in_process_gpu()) {
sadrul041ca722017-03-24 22:35:35134 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
135 switches::kSingleProcess) ||
136 base::CommandLine::ForCurrentProcess()->HasSwitch(
137 switches::kInProcessGPU));
138 }
[email protected]7a31f7c2011-03-21 23:22:04139}
140
Ken Rockot6d9ed95032019-11-13 17:20:47141GpuChildThread::~GpuChildThread() = default;
[email protected]ce79d8512013-04-22 22:44:41142
Sean Maherf36d8122022-08-05 02:33:35143void GpuChildThread::Init(const base::TimeTicks& process_start_time) {
kylechar4664a162020-09-15 03:19:34144 if (!in_process_gpu())
145 mojo::SetDefaultProcessErrorHandler(base::BindRepeating(&HandleBadMessage));
146
Sadrul Habib Chowdhury55fc2f02017-10-27 02:40:06147 viz_main_.gpu_service()->set_start_time(process_start_time);
xhwang9c8e1282015-10-10 01:54:07148
Matthew Denton66b2fa52023-10-17 00:54:22149#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
150 SandboxedProcessThreadTypeHandler::NotifyMainChildThreadCreated();
151#endif
152
xhwangded3b6e2016-05-25 05:24:51153 // When running in in-process mode, this has been set in the browser at
154 // ChromeBrowserMainPartsAndroid::PreMainMessageLoopRun().
Xiaohan Wang62737b52022-01-15 18:09:02155#if BUILDFLAG(IS_ANDROID)
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15156 if (!in_process_gpu()) {
chcunninghama4a8efb2017-03-22 16:55:02157 media::SetMediaDrmBridgeClient(
158 GetContentClient()->GetMediaDrmBridgeClient());
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57159 }
xhwangded3b6e2016-05-25 05:24:51160#endif
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15161
Georg Neis18fc5142024-12-18 00:58:41162#if BUILDFLAG(IS_CHROMEOS)
Eric Sumc8607e72022-02-18 00:48:03163 if (!in_process_gpu()) {
164 mojo::PendingRemote<font_service::mojom::FontService> font_service;
165 BindHostReceiver(font_service.InitWithNewPipeAndPassReceiver());
166 SkFontConfigInterface::SetGlobal(
167 sk_make_sp<font_service::FontLoader>(std::move(font_service)));
168 }
169#endif
170
Sebastien Marchand17797d92020-06-23 20:27:59171 memory_pressure_listener_ = std::make_unique<base::MemoryPressureListener>(
172 FROM_HERE, base::BindRepeating(&GpuChildThread::OnMemoryPressure,
173 base::Unretained(this)));
asvitkine5dc812a2016-06-07 18:20:30174}
175
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15176bool GpuChildThread::in_process_gpu() const {
Sadrul Habib Chowdhury55fc2f02017-10-27 02:40:06177 return viz_main_.gpu_service()->gpu_info().in_process_gpu;
sadrul6c5aed8c2017-01-11 23:11:44178}
179
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15180void GpuChildThread::OnInitializationFailed() {
181 OnChannelError();
182}
[email protected]96659732012-08-24 01:55:17183
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15184void GpuChildThread::OnGpuServiceConnection(viz::GpuServiceImpl* gpu_service) {
Chris Watkins88a40002017-09-28 01:16:42185 media::AndroidOverlayMojoFactoryCB overlay_factory_cb;
Xiaohan Wang62737b52022-01-15 18:09:02186#if BUILDFLAG(IS_ANDROID)
kylechared18a482019-02-07 14:07:21187 overlay_factory_cb =
188 base::BindRepeating(&GpuChildThread::CreateAndroidOverlay,
Sean Maher5b9af51f2022-11-21 15:32:47189 base::SingleThreadTaskRunner::GetCurrentDefault());
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15190 gpu_service->media_gpu_channel_manager()->SetOverlayFactory(
Chris Watkins88a40002017-09-28 01:16:42191 overlay_factory_cb);
192#endif
193
Oksana Zhuravlova04651182021-03-02 20:52:20194 if (!IsInBrowserProcess()) {
195 gpu_service->SetVisibilityChangedCallback(
196 base::BindRepeating([](bool visible) {
197 ProcessVisibilityTracker::GetInstance()->OnProcessVisibilityChanged(
198 visible);
199 }));
200 }
201
piman223a53c2016-07-21 03:41:52202 // Only set once per process instance.
Peter Boströmdd7e40ec2021-04-05 20:40:10203 service_factory_ = std::make_unique<GpuServiceFactory>(
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15204 gpu_service->gpu_preferences(),
Dan Sanders0134bec2018-04-17 20:12:12205 gpu_service->gpu_channel_manager()->gpu_driver_bug_workarounds(),
Ted Meyer68b35b92021-11-20 02:35:23206 gpu_service->gpu_feature_info(), gpu_service->gpu_info(),
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15207 gpu_service->media_gpu_channel_manager()->AsWeakPtr(),
Colin Blundellda717302025-07-08 17:10:52208 std::move(overlay_factory_cb));
Ken Rockota2924172019-12-18 03:27:05209 for (auto& receiver : pending_service_receivers_)
210 BindServiceInterface(std::move(receiver));
211 pending_service_receivers_.clear();
liberato441ca702017-05-13 16:50:38212
Ken Rockot6d9ed95032019-11-13 17:20:47213 if (GetContentClient()->gpu()) // Null in tests.
214 GetContentClient()->gpu()->GpuServiceInitialized();
piman223a53c2016-07-21 03:41:52215
Ken Rockot6d9ed95032019-11-13 17:20:47216 // Start allowing browser-exposed interfaces to be bound.
217 //
218 // NOTE: Do not add new binders within this method. Instead modify
219 // |ExposeGpuInterfacesToBrowser()| in browser_exposed_gpu_interfaces.cc, as
220 // that will ensure security review coverage.
221 mojo::BinderMap binders;
Chunbo Huad90bffb22020-09-28 15:34:36222 content::ExposeGpuInterfacesToBrowser(
Colin Blundell8b1809e2025-07-09 08:01:11223 gpu_service, gpu_service->gpu_preferences(),
Chunbo Huad90bffb22020-09-28 15:34:36224 gpu_service->gpu_channel_manager()->gpu_driver_bug_workarounds(),
225 &binders);
Ken Rockot6d9ed95032019-11-13 17:20:47226 ExposeInterfacesToBrowser(std::move(binders));
[email protected]7709e712011-01-07 17:57:31227}
228
Sadrul Habib Chowdhury97c6f1f2018-03-02 01:21:16229void GpuChildThread::PostCompositorThreadCreated(
230 base::SingleThreadTaskRunner* task_runner) {
231 auto* gpu_client = GetContentClient()->gpu();
232 if (gpu_client)
233 gpu_client->PostCompositorThreadCreated(task_runner);
234}
235
Wez6979109b2018-09-07 17:30:56236void GpuChildThread::QuitMainMessageLoop() {
Eric Karl23af711f2018-11-02 20:47:34237 quit_closure_.Run();
Wez6979109b2018-09-07 17:30:56238}
239
Khushal0aac62072018-06-01 19:33:17240void GpuChildThread::OnMemoryPressure(
241 base::MemoryPressureListener::MemoryPressureLevel level) {
Takashi Sakamotobb074802018-10-15 07:35:27242 if (level != base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL)
243 return;
Khushal0aac62072018-06-01 19:33:17244
Khushal0aac62072018-06-01 19:33:17245 if (viz_main_.discardable_shared_memory_manager())
246 viz_main_.discardable_shared_memory_manager()->ReleaseFreeMemory();
247 SkGraphics::PurgeAllCaches();
248}
249
Eric Karl23af711f2018-11-02 20:47:34250void GpuChildThread::QuitSafelyHelper(
251 scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
252 // Post a new task (even if we're called on the |task_runner|'s thread) to
253 // ensure that we are post-init.
254 task_runner->PostTask(
255 FROM_HERE, base::BindOnce([]() {
256 ChildThreadImpl* current_child_thread = ChildThreadImpl::current();
257 if (!current_child_thread)
258 return;
259 GpuChildThread* gpu_child_thread =
260 static_cast<GpuChildThread*>(current_child_thread);
Patrick Todf5911c2020-05-12 19:31:42261 gpu_child_thread->viz_main_.ExitProcess(
262 viz::ExitCode::RESULT_CODE_NORMAL_EXIT);
Eric Karl23af711f2018-11-02 20:47:34263 }));
264}
265
266// Returns a closure which calls into the VizMainImpl to perform shutdown
267// before quitting the main message loop. Must be called on the main thread.
268base::RepeatingClosure GpuChildThread::MakeQuitSafelyClosure() {
269 return base::BindRepeating(&GpuChildThread::QuitSafelyHelper,
Sean Maher5b9af51f2022-11-21 15:32:47270 base::SingleThreadTaskRunner::GetCurrentDefault());
Eric Karl23af711f2018-11-02 20:47:34271}
272
Xiaohan Wang62737b52022-01-15 18:09:02273#if BUILDFLAG(IS_ANDROID)
liberato441ca702017-05-13 16:50:38274// static
275std::unique_ptr<media::AndroidOverlay> GpuChildThread::CreateAndroidOverlay(
Chris Watkins88a40002017-09-28 01:16:42276 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
liberato441ca702017-05-13 16:50:38277 const base::UnguessableToken& routing_token,
278 media::AndroidOverlayConfig config) {
Miyoung Shin18de6bf2019-10-17 07:06:24279 mojo::PendingRemote<media::mojom::AndroidOverlayProvider> overlay_provider;
Chris Watkins88a40002017-09-28 01:16:42280 if (main_task_runner->RunsTasksInCurrentSequence()) {
Miyoung Shin18de6bf2019-10-17 07:06:24281 ChildThread::Get()->BindHostReceiver(
282 overlay_provider.InitWithNewPipeAndPassReceiver());
Chris Watkins88a40002017-09-28 01:16:42283 } else {
Chris Watkins88a40002017-09-28 01:16:42284 main_task_runner->PostTask(
Ken Rockot47c47d862019-09-26 17:38:07285 FROM_HERE,
286 base::BindOnce(
Miyoung Shin18de6bf2019-10-17 07:06:24287 [](mojo::PendingReceiver<media::mojom::AndroidOverlayProvider>
288 receiver) {
289 ChildThread::Get()->BindHostReceiver(std::move(receiver));
Ken Rockot47c47d862019-09-26 17:38:07290 },
Miyoung Shin18de6bf2019-10-17 07:06:24291 overlay_provider.InitWithNewPipeAndPassReceiver()));
Chris Watkins88a40002017-09-28 01:16:42292 }
293
Jeremy Roman04f27c372017-10-27 15:20:55294 return std::make_unique<media::MojoAndroidOverlay>(
[email protected]9a635ee2017-12-01 21:38:50295 std::move(overlay_provider), std::move(config), routing_token);
liberato441ca702017-05-13 16:50:38296}
297#endif
298
[email protected]eb398192012-10-22 20:16:19299} // namespace content