910e62b5创建于 1月15日历史提交
// 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/profiler/thread_group_profiler.h"
#include "base/task/single_thread_task_runner.h"
#include "base/token.h"
#include "build/build_config.h"
#include "chrome/common/profiler/chrome_thread_group_profiler_client.h"
#include "chrome/common/profiler/chrome_thread_profiler_client.h"
#include "chrome/common/profiler/core_unwinders.h"
#include "chrome/common/profiler/thread_profiler_configuration.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)
#include "chromeos/ash/experiences/arc/video_accelerator/protected_buffer_manager.h"
#include "chromeos/components/cdm_factory_daemon/chromeos_cdm_factory.h"
#include "chromeos/components/cdm_factory_daemon/mojom/browser_cdm_factory.mojom.h"
#include "ui/ozone/public/ozone_platform.h"         // nogncheck
#include "ui/ozone/public/surface_factory_ozone.h"  // nogncheck
#endif  // BUILDFLAG(IS_CHROMEOS)

ChromeContentGpuClient::ChromeContentGpuClient() {
  base::ThreadGroupProfiler::SetClient(
      std::make_unique<ChromeThreadGroupProfilerClient>());
  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)
  protected_buffer_manager_ = new arc::ProtectedBufferManager();
#endif
}

ChromeContentGpuClient::~ChromeContentGpuClient() = default;

void ChromeContentGpuClient::GpuServiceInitialized() {
#if BUILDFLAG(IS_CHROMEOS)
  ui::OzonePlatform::GetInstance()
      ->GetSurfaceFactoryOzone()
      ->SetGetProtectedNativePixmapDelegate(base::BindRepeating(
          &arc::ProtectedBufferManager::GetProtectedNativePixmapFor,
          base::Unretained(protected_buffer_manager_.get())));
  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(
    viz::GpuServiceImpl* gpu_service,
    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_service, 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)
scoped_refptr<arc::ProtectedBufferManager>
ChromeContentGpuClient::GetProtectedBufferManager() {
  return protected_buffer_manager_;
}
#endif  // BUILDFLAG(IS_CHROMEOS)