blob: 0ae0a6338508af39e7e1985ccc4a5b4ecdf6eebc [file] [log] [blame]
[email protected]f0918242012-02-18 00:30:501// 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
[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>
dchengf63a1252015-12-26 20:43:138#include <utility>
avi66a07722015-12-25 23:38:129
Khushal0aac62072018-06-01 19:33:1710#include "base/allocator/allocator_extension.h"
[email protected]80751052011-11-12 17:10:5811#include "base/bind.h"
Sebastien Marchand17fa2782019-01-25 19:28:1012#include "base/bind_helpers.h"
rockotcaccf782016-06-29 23:39:1613#include "base/callback_helpers.h"
kylechar150e09e12017-10-19 13:57:5214#include "base/command_line.h"
bend6234442017-04-24 22:51:1315#include "base/memory/weak_ptr.h"
Tom McKee14679152020-01-20 16:06:5216#include "base/power_monitor/power_monitor.h"
17#include "base/power_monitor/power_monitor_device_source.h"
Gabriel Charette53a9ef812017-07-26 12:36:2318#include "base/run_loop.h"
Gabriel Charette5ff87ce2017-05-16 18:03:4519#include "base/sequenced_task_runner.h"
bend6234442017-04-24 22:51:1320#include "base/threading/thread_checker.h"
[email protected]274aa5882010-07-15 21:12:2321#include "build/build_config.h"
[email protected]10208ea2013-06-06 20:08:0322#include "content/child/child_process.h"
Ken Rockot6d9ed95032019-11-13 17:20:4723#include "content/gpu/browser_exposed_gpu_interfaces.h"
ben507aa812016-08-10 23:26:1924#include "content/gpu/gpu_service_factory.h"
[email protected]085170ca2012-05-17 20:27:2825#include "content/public/common/content_client.h"
[email protected]c9e2cbbb2012-05-12 21:17:2726#include "content/public/common/content_switches.h"
chiniforooshan701fa212017-04-06 22:22:4927#include "content/public/common/service_names.mojom.h"
kcwu08377ad2016-02-18 19:12:4228#include "content/public/gpu/content_gpu_client.h"
ericrk8c0b7bf62017-03-17 20:07:2329#include "gpu/command_buffer/common/activity_flags.h"
Dan Sanders0134bec2018-04-17 20:12:1230#include "gpu/ipc/service/gpu_channel_manager.h"
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:5731#include "gpu/ipc/service/gpu_init.h"
sadrul2fb7e152016-08-30 05:21:4532#include "gpu/ipc/service/gpu_watchdog_thread.h"
[email protected]8c81e9ecc2012-04-25 00:42:2733#include "ipc/ipc_sync_message_filter.h"
xhwangb2402d92016-10-15 07:29:3734#include "media/gpu/ipc/service/media_gpu_channel_manager.h"
Ken Rockot6d9ed95032019-11-13 17:20:4735#include "mojo/public/cpp/bindings/binder_map.h"
Miyoung Shin18de6bf2019-10-17 07:06:2436#include "mojo/public/cpp/bindings/pending_receiver.h"
37#include "mojo/public/cpp/bindings/pending_remote.h"
Ken Rockot47c47d862019-09-26 17:38:0738#include "services/metrics/public/cpp/mojo_ukm_recorder.h"
39#include "services/metrics/public/mojom/ukm_interface.mojom.h"
bend6234442017-04-24 22:51:1340#include "services/service_manager/public/cpp/binder_registry.h"
Miyoung Shin2be27f52019-07-27 15:35:3941#include "services/viz/privileged/mojom/gl/gpu_service.mojom.h"
Khushal0aac62072018-06-01 19:33:1742#include "third_party/skia/include/core/SkGraphics.h"
[email protected]7709e712011-01-07 17:57:3143
watkad8743d2016-04-27 20:27:4944#if defined(OS_ANDROID)
chcunninghama4a8efb2017-03-22 16:55:0245#include "media/base/android/media_drm_bridge_client.h"
liberato441ca702017-05-13 16:50:3846#include "media/mojo/clients/mojo_android_overlay.h"
watkad8743d2016-04-27 20:27:4947#endif
48
[email protected]eb398192012-10-22 20:16:1949namespace content {
[email protected]7709e712011-01-07 17:57:3150namespace {
51
sadrul16d36322017-03-29 00:57:1652ChildThreadImpl::Options GetOptions() {
skyostilf28ccd0b2015-03-04 20:20:4653 ChildThreadImpl::Options::Builder builder;
alexst6154ce772015-01-21 12:41:4154
wittman757af872016-08-16 00:13:4655 builder.ConnectToBrowser(true);
Ken Rockot6d9ed95032019-11-13 17:20:4756 builder.ExposesInterfacesToBrowser();
wittman757af872016-08-16 00:13:4657
skyostilf28ccd0b2015-03-04 20:20:4658 return builder.Build();
alexst6154ce772015-01-21 12:41:4159}
60
Ken Rockot47c47d862019-09-26 17:38:0761viz::VizMainImpl::ExternalDependencies CreateVizMainDependencies() {
Sadrul Habib Chowdhury55fc2f02017-10-27 02:40:0662 viz::VizMainImpl::ExternalDependencies deps;
Tom McKee14679152020-01-20 16:06:5263 if (!base::PowerMonitor::IsInitialized()) {
64 deps.power_monitor_source =
65 std::make_unique<base::PowerMonitorDeviceSource>();
66 }
Peng Huange3b8c1d2019-03-05 17:21:1267 if (GetContentClient()->gpu()) {
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:1568 deps.sync_point_manager = GetContentClient()->gpu()->GetSyncPointManager();
Peng Huange3b8c1d2019-03-05 17:21:1269 deps.shared_image_manager =
70 GetContentClient()->gpu()->GetSharedImageManager();
Bo Liua7b2ce62019-08-02 22:16:2371 deps.viz_compositor_thread_runner =
72 GetContentClient()->gpu()->GetVizCompositorThreadRunner();
Peng Huange3b8c1d2019-03-05 17:21:1273 }
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:1574 auto* process = ChildProcess::current();
75 deps.shutdown_event = process->GetShutDownEvent();
76 deps.io_thread_task_runner = process->io_task_runner();
Ken Rockot47c47d862019-09-26 17:38:0777
78 mojo::PendingRemote<ukm::mojom::UkmRecorderInterface> ukm_recorder;
79 ChildThread::Get()->BindHostReceiver(
80 ukm_recorder.InitWithNewPipeAndPassReceiver());
81 deps.ukm_recorder =
82 std::make_unique<ukm::MojoUkmRecorder>(std::move(ukm_recorder));
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:1583 return deps;
84}
85
[email protected]e6ff5a32011-01-31 20:36:2286} // namespace
[email protected]9158f2f2011-01-27 21:08:5787
Wez6979109b2018-09-07 17:30:5688GpuChildThread::GpuChildThread(base::RepeatingClosure quit_closure,
Dale Curtis1b6becebb2020-03-30 20:13:3589 std::unique_ptr<gpu::GpuInit> gpu_init)
Wez6979109b2018-09-07 17:30:5690 : GpuChildThread(std::move(quit_closure),
91 GetOptions(),
Dale Curtis1b6becebb2020-03-30 20:13:3592 std::move(gpu_init)) {}
[email protected]9158f2f2011-01-27 21:08:5793
sadrul6d41b822017-04-02 03:38:5094GpuChildThread::GpuChildThread(const InProcessChildThreadParams& params,
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:5795 std::unique_ptr<gpu::GpuInit> gpu_init)
Wez6979109b2018-09-07 17:30:5696 : GpuChildThread(base::DoNothing(),
97 ChildThreadImpl::Options::Builder()
sadrul041ca722017-03-24 22:35:3598 .InBrowserProcess(params)
sadrul041ca722017-03-24 22:35:3599 .ConnectToBrowser(true)
Ken Rockot6d9ed95032019-11-13 17:20:47100 .ExposesInterfacesToBrowser()
sadrul041ca722017-03-24 22:35:35101 .Build(),
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57102 std::move(gpu_init)) {}
sadrul041ca722017-03-24 22:35:35103
Wez6979109b2018-09-07 17:30:56104GpuChildThread::GpuChildThread(base::RepeatingClosure quit_closure,
Ken Rockot6d9ed95032019-11-13 17:20:47105 ChildThreadImpl::Options options,
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57106 std::unique_ptr<gpu::GpuInit> gpu_init)
Ken Rockot6d9ed95032019-11-13 17:20:47107 : ChildThreadImpl(MakeQuitSafelyClosure(), std::move(options)),
Ken Rockot47c47d862019-09-26 17:38:07108 viz_main_(this, CreateVizMainDependencies(), std::move(gpu_init)),
Jeremy Roman3bca4bf2019-07-11 03:41:25109 quit_closure_(std::move(quit_closure)) {
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15110 if (in_process_gpu()) {
sadrul041ca722017-03-24 22:35:35111 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
112 switches::kSingleProcess) ||
113 base::CommandLine::ForCurrentProcess()->HasSwitch(
114 switches::kInProcessGPU));
115 }
[email protected]7a31f7c2011-03-21 23:22:04116}
117
Ken Rockot6d9ed95032019-11-13 17:20:47118GpuChildThread::~GpuChildThread() = default;
[email protected]ce79d8512013-04-22 22:44:41119
[email protected]7a31f7c2011-03-21 23:22:04120void GpuChildThread::Init(const base::Time& process_start_time) {
Sadrul Habib Chowdhury55fc2f02017-10-27 02:40:06121 viz_main_.gpu_service()->set_start_time(process_start_time);
xhwang9c8e1282015-10-10 01:54:07122
xhwangded3b6e2016-05-25 05:24:51123 // When running in in-process mode, this has been set in the browser at
124 // ChromeBrowserMainPartsAndroid::PreMainMessageLoopRun().
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15125#if defined(OS_ANDROID)
126 if (!in_process_gpu()) {
chcunninghama4a8efb2017-03-22 16:55:02127 media::SetMediaDrmBridgeClient(
128 GetContentClient()->GetMediaDrmBridgeClient());
Sadrul Habib Chowdhurydb9021e2017-10-03 03:07:57129 }
xhwangded3b6e2016-05-25 05:24:51130#endif
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15131
Sam McNally52e50282017-11-29 00:54:02132 blink::AssociatedInterfaceRegistry* associated_registry =
133 &associated_interfaces_;
kylechared18a482019-02-07 14:07:21134 associated_registry->AddInterface(base::BindRepeating(
Sadrul Habib Chowdhury55fc2f02017-10-27 02:40:06135 &GpuChildThread::CreateVizMainService, base::Unretained(this)));
bend6234442017-04-24 22:51:13136
Khushal0aac62072018-06-01 19:33:17137 memory_pressure_listener_ =
138 std::make_unique<base::MemoryPressureListener>(base::BindRepeating(
139 &GpuChildThread::OnMemoryPressure, base::Unretained(this)));
asvitkine5dc812a2016-06-07 18:20:30140}
141
Sadrul Habib Chowdhury55fc2f02017-10-27 02:40:06142void GpuChildThread::CreateVizMainService(
Shimi Zhang88ae9222019-07-19 16:54:16143 mojo::PendingAssociatedReceiver<viz::mojom::VizMain> pending_receiver) {
144 viz_main_.BindAssociated(std::move(pending_receiver));
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15145}
146
147bool GpuChildThread::in_process_gpu() const {
Sadrul Habib Chowdhury55fc2f02017-10-27 02:40:06148 return viz_main_.gpu_service()->gpu_info().in_process_gpu;
sadrul6c5aed8c2017-01-11 23:11:44149}
150
[email protected]7a31f7c2011-03-21 23:22:04151bool GpuChildThread::Send(IPC::Message* msg) {
152 // The GPU process must never send a synchronous IPC message to the browser
[email protected]4c0e289d2011-06-01 03:45:51153 // process. This could result in deadlock.
154 DCHECK(!msg->is_sync());
[email protected]7a31f7c2011-03-21 23:22:04155
jam8a021512a2015-02-03 18:16:08156 return ChildThreadImpl::Send(msg);
[email protected]7a31f7c2011-03-21 23:22:04157}
158
sadrul72aae8a2017-01-24 04:52:32159void GpuChildThread::OnAssociatedInterfaceRequest(
160 const std::string& name,
161 mojo::ScopedInterfaceEndpointHandle handle) {
Ken Rockot26e4e802018-07-31 15:03:33162 if (!associated_interfaces_.TryBindInterface(name, &handle))
rockot70bbb59492017-01-25 00:56:51163 ChildThreadImpl::OnAssociatedInterfaceRequest(name, std::move(handle));
markdittmer43e79f02016-03-11 14:50:08164}
165
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15166void GpuChildThread::OnInitializationFailed() {
167 OnChannelError();
168}
[email protected]96659732012-08-24 01:55:17169
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15170void GpuChildThread::OnGpuServiceConnection(viz::GpuServiceImpl* gpu_service) {
Chris Watkins88a40002017-09-28 01:16:42171 media::AndroidOverlayMojoFactoryCB overlay_factory_cb;
172#if defined(OS_ANDROID)
kylechared18a482019-02-07 14:07:21173 overlay_factory_cb =
174 base::BindRepeating(&GpuChildThread::CreateAndroidOverlay,
175 base::ThreadTaskRunnerHandle::Get());
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15176 gpu_service->media_gpu_channel_manager()->SetOverlayFactory(
Chris Watkins88a40002017-09-28 01:16:42177 overlay_factory_cb);
178#endif
179
piman223a53c2016-07-21 03:41:52180 // Only set once per process instance.
sadrul72aae8a2017-01-24 04:52:32181 service_factory_.reset(new GpuServiceFactory(
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15182 gpu_service->gpu_preferences(),
Dan Sanders0134bec2018-04-17 20:12:12183 gpu_service->gpu_channel_manager()->gpu_driver_bug_workarounds(),
Khushala55414a2018-10-09 17:13:53184 gpu_service->gpu_feature_info(),
Sadrul Habib Chowdhurydbe4da92017-10-12 15:53:15185 gpu_service->media_gpu_channel_manager()->AsWeakPtr(),
Jeffrey Kardatzke67d88fb52019-10-08 19:02:05186 gpu_service->gpu_memory_buffer_factory(), std::move(overlay_factory_cb)));
Ken Rockota2924172019-12-18 03:27:05187 for (auto& receiver : pending_service_receivers_)
188 BindServiceInterface(std::move(receiver));
189 pending_service_receivers_.clear();
liberato441ca702017-05-13 16:50:38190
Ken Rockot6d9ed95032019-11-13 17:20:47191 if (GetContentClient()->gpu()) // Null in tests.
192 GetContentClient()->gpu()->GpuServiceInitialized();
piman223a53c2016-07-21 03:41:52193
Ken Rockot6d9ed95032019-11-13 17:20:47194 // Start allowing browser-exposed interfaces to be bound.
195 //
196 // NOTE: Do not add new binders within this method. Instead modify
197 // |ExposeGpuInterfacesToBrowser()| in browser_exposed_gpu_interfaces.cc, as
198 // that will ensure security review coverage.
199 mojo::BinderMap binders;
200 content::ExposeGpuInterfacesToBrowser(gpu_service->gpu_preferences(),
201 &binders);
202 ExposeInterfacesToBrowser(std::move(binders));
[email protected]7709e712011-01-07 17:57:31203}
204
Sadrul Habib Chowdhury97c6f1f2018-03-02 01:21:16205void GpuChildThread::PostCompositorThreadCreated(
206 base::SingleThreadTaskRunner* task_runner) {
207 auto* gpu_client = GetContentClient()->gpu();
208 if (gpu_client)
209 gpu_client->PostCompositorThreadCreated(task_runner);
210}
211
Wez6979109b2018-09-07 17:30:56212void GpuChildThread::QuitMainMessageLoop() {
Eric Karl23af711f2018-11-02 20:47:34213 quit_closure_.Run();
Wez6979109b2018-09-07 17:30:56214}
215
Khushal0aac62072018-06-01 19:33:17216void GpuChildThread::OnMemoryPressure(
217 base::MemoryPressureListener::MemoryPressureLevel level) {
Takashi Sakamotobb074802018-10-15 07:35:27218 if (level != base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL)
219 return;
Khushal0aac62072018-06-01 19:33:17220
Khushal0aac62072018-06-01 19:33:17221 base::allocator::ReleaseFreeMemory();
222 if (viz_main_.discardable_shared_memory_manager())
223 viz_main_.discardable_shared_memory_manager()->ReleaseFreeMemory();
224 SkGraphics::PurgeAllCaches();
225}
226
Eric Karl23af711f2018-11-02 20:47:34227void GpuChildThread::QuitSafelyHelper(
228 scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
229 // Post a new task (even if we're called on the |task_runner|'s thread) to
230 // ensure that we are post-init.
231 task_runner->PostTask(
232 FROM_HERE, base::BindOnce([]() {
233 ChildThreadImpl* current_child_thread = ChildThreadImpl::current();
234 if (!current_child_thread)
235 return;
236 GpuChildThread* gpu_child_thread =
237 static_cast<GpuChildThread*>(current_child_thread);
Patrick Todf5911c2020-05-12 19:31:42238 gpu_child_thread->viz_main_.ExitProcess(
239 viz::ExitCode::RESULT_CODE_NORMAL_EXIT);
Eric Karl23af711f2018-11-02 20:47:34240 }));
241}
242
243// Returns a closure which calls into the VizMainImpl to perform shutdown
244// before quitting the main message loop. Must be called on the main thread.
245base::RepeatingClosure GpuChildThread::MakeQuitSafelyClosure() {
246 return base::BindRepeating(&GpuChildThread::QuitSafelyHelper,
247 base::ThreadTaskRunnerHandle::Get());
248}
249
liberato441ca702017-05-13 16:50:38250#if defined(OS_ANDROID)
251// static
252std::unique_ptr<media::AndroidOverlay> GpuChildThread::CreateAndroidOverlay(
Chris Watkins88a40002017-09-28 01:16:42253 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
liberato441ca702017-05-13 16:50:38254 const base::UnguessableToken& routing_token,
255 media::AndroidOverlayConfig config) {
Miyoung Shin18de6bf2019-10-17 07:06:24256 mojo::PendingRemote<media::mojom::AndroidOverlayProvider> overlay_provider;
Chris Watkins88a40002017-09-28 01:16:42257 if (main_task_runner->RunsTasksInCurrentSequence()) {
Miyoung Shin18de6bf2019-10-17 07:06:24258 ChildThread::Get()->BindHostReceiver(
259 overlay_provider.InitWithNewPipeAndPassReceiver());
Chris Watkins88a40002017-09-28 01:16:42260 } else {
Chris Watkins88a40002017-09-28 01:16:42261 main_task_runner->PostTask(
Ken Rockot47c47d862019-09-26 17:38:07262 FROM_HERE,
263 base::BindOnce(
Miyoung Shin18de6bf2019-10-17 07:06:24264 [](mojo::PendingReceiver<media::mojom::AndroidOverlayProvider>
265 receiver) {
266 ChildThread::Get()->BindHostReceiver(std::move(receiver));
Ken Rockot47c47d862019-09-26 17:38:07267 },
Miyoung Shin18de6bf2019-10-17 07:06:24268 overlay_provider.InitWithNewPipeAndPassReceiver()));
Chris Watkins88a40002017-09-28 01:16:42269 }
270
Jeremy Roman04f27c372017-10-27 15:20:55271 return std::make_unique<media::MojoAndroidOverlay>(
[email protected]9a635ee2017-12-01 21:38:50272 std::move(overlay_provider), std::move(config), routing_token);
liberato441ca702017-05-13 16:50:38273}
274#endif
275
[email protected]eb398192012-10-22 20:16:19276} // namespace content