blob: 24dcb4d079168fab31b837bf4a9f91224d0a6d41 [file] [log] [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/gpu/chrome_content_gpu_client.h"
#include <string>
#include <utility>
#include "base/check.h"
#include "base/command_line.h"
#include "base/functional/bind.h"
#include "base/task/single_thread_task_runner.h"
#include "base/token.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/common/profiler/chrome_thread_profiler_client.h"
#include "chrome/common/profiler/thread_profiler_configuration.h"
#include "chrome/common/profiler/unwind_util.h"
#include "chrome/gpu/browser_exposed_gpu_interfaces.h"
#include "components/heap_profiling/in_process/heap_profiler_controller.h"
#include "components/metrics/call_stacks/call_stack_profile_builder.h"
#include "components/sampling_profiler/process_type.h"
#include "components/sampling_profiler/thread_profiler.h"
#include "content/public/child/child_thread.h"
#include "content/public/common/content_switches.h"
#include "media/media_buildflags.h"
#include "services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/components/arc/video_accelerator/protected_buffer_manager.h"
#include "ui/ozone/public/ozone_platform.h" // nogncheck
#include "ui/ozone/public/surface_factory_ozone.h" // nogncheck
#endif
#if BUILDFLAG(IS_CHROMEOS)
#include "chromeos/components/cdm_factory_daemon/chromeos_cdm_factory.h"
#include "chromeos/components/cdm_factory_daemon/mojom/browser_cdm_factory.mojom.h"
#endif // BUILDFLAG(IS_CHROMEOS)
ChromeContentGpuClient::ChromeContentGpuClient() {
sampling_profiler::ThreadProfiler::SetClient(
std::make_unique<ChromeThreadProfilerClient>());
// The profiler can't start before the sandbox is initialized on
// ChromeOS due to ChromeOS's sandbox initialization code's use of
// AssertSingleThreaded().
#if !BUILDFLAG(IS_CHROMEOS)
main_thread_profiler_ =
sampling_profiler::ThreadProfiler::CreateAndStartOnMainThread();
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
protected_buffer_manager_ = new arc::ProtectedBufferManager();
#endif
}
ChromeContentGpuClient::~ChromeContentGpuClient() = default;
void ChromeContentGpuClient::GpuServiceInitialized() {
#if BUILDFLAG(IS_CHROMEOS_ASH)
ui::OzonePlatform::GetInstance()
->GetSurfaceFactoryOzone()
->SetGetProtectedNativePixmapDelegate(base::BindRepeating(
&arc::ProtectedBufferManager::GetProtectedNativePixmapFor,
base::Unretained(protected_buffer_manager_.get())));
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
#if BUILDFLAG(IS_CHROMEOS)
content::ChildThread::Get()->BindHostReceiver(
chromeos::ChromeOsCdmFactory::GetBrowserCdmFactoryReceiver());
#endif // BUILDFLAG(IS_CHROMEOS)
// This doesn't work in single-process mode.
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kSingleProcess) &&
!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kInProcessGPU)) {
const auto* heap_profiler_controller =
heap_profiling::HeapProfilerController::GetInstance();
// The HeapProfilerController should have been created in
// ChromeMainDelegate::PostEarlyInitialization.
CHECK(heap_profiler_controller);
if (ThreadProfilerConfiguration::Get()
->IsProfilerEnabledForCurrentProcess() ||
heap_profiler_controller->IsEnabled()) {
sampling_profiler::ThreadProfiler::SetMainThreadTaskRunner(
base::SingleThreadTaskRunner::GetCurrentDefault());
mojo::PendingRemote<metrics::mojom::CallStackProfileCollector> collector;
content::ChildThread::Get()->BindHostReceiver(
collector.InitWithNewPipeAndPassReceiver());
metrics::CallStackProfileBuilder::
SetParentProfileCollectorForChildProcess(std::move(collector));
}
}
}
void ChromeContentGpuClient::ExposeInterfacesToBrowser(
const gpu::GpuPreferences& gpu_preferences,
const gpu::GpuDriverBugWorkarounds& gpu_workarounds,
mojo::BinderMap* binders) {
// NOTE: Do not add binders directly within this method. Instead, modify the
// definition of |ExposeChromeGpuInterfacesToBrowser()|, as this ensures
// security review coverage.
ExposeChromeGpuInterfacesToBrowser(this, gpu_preferences, gpu_workarounds,
binders);
}
void ChromeContentGpuClient::PostSandboxInitialized() {
#if BUILDFLAG(IS_CHROMEOS)
DCHECK(!main_thread_profiler_);
main_thread_profiler_ =
sampling_profiler::ThreadProfiler::CreateAndStartOnMainThread();
#endif // BUILDFLAG(IS_CHROMEOS)
}
void ChromeContentGpuClient::PostIOThreadCreated(
base::SingleThreadTaskRunner* io_task_runner) {
io_task_runner->PostTask(
FROM_HERE,
base::BindOnce(&sampling_profiler::ThreadProfiler::StartOnChildThread,
sampling_profiler::ProfilerThreadType::kIo));
}
void ChromeContentGpuClient::PostCompositorThreadCreated(
base::SingleThreadTaskRunner* task_runner) {
task_runner->PostTask(
FROM_HERE,
base::BindOnce(&sampling_profiler::ThreadProfiler::StartOnChildThread,
sampling_profiler::ProfilerThreadType::kCompositor));
// Enable stack sampling for tracing.
// We pass in CreateCoreUnwindersFactory here since it lives in the chrome/
// layer while TracingSamplerProfiler is outside of chrome/.
task_runner->PostTask(
FROM_HERE, base::BindOnce(&tracing::TracingSamplerProfiler::
CreateOnChildThreadWithCustomUnwinders,
base::BindRepeating(
&CreateCoreUnwindersFactory)));
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
scoped_refptr<arc::ProtectedBufferManager>
ChromeContentGpuClient::GetProtectedBufferManager() {
return protected_buffer_manager_;
}
#endif // BUILDFLAG(IS_CHROMEOS_ASH)