赞
踩
接前一篇文章:Chromium源码由浅入深(四)
上回书一步步跟踪,最终跟踪到components/viz/service/gl/gpu_service_impl.cc中相邻的两个函数(方法),分别是GpuServiceImpl::InitializeWithHost()和GpuServiceImpl::UpdateGPUInfoGL()。再次贴出代码如下:
- void GpuServiceImpl::UpdateGPUInfoGL() {
- DCHECK(main_runner_->BelongsToCurrentThread());
- gpu::CollectGraphicsInfoGL(&gpu_info_, GetContextState()->display());
- gpu_host_->DidUpdateGPUInfo(gpu_info_);
- }
-
- void GpuServiceImpl::InitializeWithHost(
- mojo::PendingRemote<mojom::GpuHost> pending_gpu_host,
- gpu::GpuProcessActivityFlags activity_flags,
- scoped_refptr<gl::GLSurface> default_offscreen_surface,
- gpu::SyncPointManager* sync_point_manager,
- gpu::SharedImageManager* shared_image_manager,
- gpu::Scheduler* scheduler,
- base::WaitableEvent* shutdown_event) {
- DCHECK(main_runner_->BelongsToCurrentThread());
-
- mojo::Remote<mojom::GpuHost> gpu_host(std::move(pending_gpu_host));
- gpu_host->DidInitialize(gpu_info_, gpu_feature_info_,
- gpu_info_for_hardware_gpu_,
- gpu_feature_info_for_hardware_gpu_, gpu_extra_info_);
- gpu_host_ = mojo::SharedRemote<mojom::GpuHost>(gpu_host.Unbind(), io_runner_);
- if (!in_host_process()) {
- // The global callback is reset from the dtor. So Unretained() here is safe.
- // Note that the callback can be called from any thread. Consequently, the
- // callback cannot use a WeakPtr.
- GetLogMessageManager()->InstallPostInitializeLogHandler(base::BindRepeating(
- &GpuServiceImpl::RecordLogMessage, base::Unretained(this)));
- }
-
- if (!sync_point_manager) {
- owned_sync_point_manager_ = std::make_unique<gpu::SyncPointManager>();
- sync_point_manager = owned_sync_point_manager_.get();
- }
-
- if (!shared_image_manager) {
- // When using real buffers for testing overlay configurations, we need
- // access to SharedImageManager on the viz thread to obtain the buffer
- // corresponding to a mailbox.
- const bool display_context_on_another_thread =
- features::IsDrDcEnabled() && !gpu_driver_bug_workarounds_.disable_drdc;
- bool thread_safe_manager = display_context_on_another_thread;
- // Raw draw needs to access shared image backing on the compositor thread.
- thread_safe_manager |= features::IsUsingRawDraw();
- #if BUILDFLAG(IS_OZONE)
- thread_safe_manager |= features::ShouldUseRealBuffersForPageFlipTest();
- #endif
- owned_shared_image_manager_ = std::make_unique<gpu::SharedImageManager>(
- thread_safe_manager, display_context_on_another_thread);
- shared_image_manager = owned_shared_image_manager_.get();
- #if BUILDFLAG(IS_OZONE)
- } else {
- // With this feature enabled, we don't expect to receive an external
- // SharedImageManager.
- DCHECK(!features::ShouldUseRealBuffersForPageFlipTest());
- #endif
- }
-
- shutdown_event_ = shutdown_event;
- if (!shutdown_event_) {
- owned_shutdown_event_ = std::make_unique<base::WaitableEvent>(
- base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- shutdown_event_ = owned_shutdown_event_.get();
- }
-
- if (scheduler) {
- scheduler_ = scheduler;
- } else {
- owned_scheduler_ =
- std::make_unique<gpu::Scheduler>(sync_point_manager, gpu_preferences_);
- scheduler_ = owned_scheduler_.get();
- }
-
- // Defer creation of the render thread. This is to prevent it from handling
- // IPC messages before the sandbox has been enabled and all other necessary
- // initialization has succeeded.
- gpu_channel_manager_ = std::make_unique<gpu::GpuChannelManager>(
- gpu_preferences_, this, watchdog_thread_.get(), main_runner_, io_runner_,
- scheduler_, sync_point_manager, shared_image_manager,
- gpu_memory_buffer_factory_.get(), gpu_feature_info_,
- std::move(activity_flags), std::move(default_offscreen_surface),
- image_decode_accelerator_worker_.get(), vulkan_context_provider(),
- metal_context_provider_.get(), dawn_context_provider());
-
- media_gpu_channel_manager_ = std::make_unique<media::MediaGpuChannelManager>(
- gpu_channel_manager_.get());
-
- // Create and Initialize compositor gpu thread.
- compositor_gpu_thread_ = CompositorGpuThread::Create(
- gpu_channel_manager_.get(),
- #if BUILDFLAG(ENABLE_VULKAN)
- vulkan_implementation_,
- vulkan_context_provider_ ? vulkan_context_provider_->GetDeviceQueue()
- : nullptr,
- #else
- nullptr, nullptr,
- #endif
- gpu_channel_manager_->default_offscreen_surface()
- ? gpu_channel_manager_->default_offscreen_surface()->GetGLDisplay()
- : nullptr,
- !!watchdog_thread_);
- }
实际上这中间还有小插曲,这两个函数还不是最终调用的GpuProcessHost::DidInitialize()和GpuProcessHost::DidUpdateGPUInfo(),而是中间还有个delegate。在components/viz/host/gpu_host_impl.cc中,代码分别如下:
- void GpuHostImpl::DidInitialize(
- const gpu::GPUInfo& gpu_info,
- const gpu::GpuFeatureInfo& gpu_feature_info,
- const absl::optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu,
- const absl::optional<gpu::GpuFeatureInfo>&
- gpu_feature_info_for_hardware_gpu,
- const gfx::GpuExtraInfo& gpu_extra_info) {
- UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", true);
-
- delegate_->DidInitialize(gpu_info, gpu_feature_info,
- gpu_info_for_hardware_gpu,
- gpu_feature_info_for_hardware_gpu, gpu_extra_info);
-
- if (!params_.disable_gpu_shader_disk_cache) {
- SetChannelDiskCacheHandle(gpu::kDisplayCompositorClientId,
- gpu::kDisplayCompositorGpuDiskCacheHandle);
- SetChannelDiskCacheHandle(gpu::kGrShaderCacheClientId,
- gpu::kGrShaderGpuDiskCacheHandle);
- }
- }
- void GpuHostImpl::DidUpdateGPUInfo(const gpu::GPUInfo& gpu_info) {
- delegate_->DidUpdateGPUInfo(gpu_info);
- }
不过这些都是C++的小伎俩而已,不是本书的重点,一带而过就好。还是回到正题。
由上边GpuServiceImpl::InitializeWithHost()的代码可以看到,它的参数中并没有gpu_info_,但是却在调用的时候直接传入了gpu_info_,如下所示:
- void GpuServiceImpl::InitializeWithHost(
- mojo::PendingRemote<mojom::GpuHost> pending_gpu_host,
- gpu::GpuProcessActivityFlags activity_flags,
- scoped_refptr<gl::GLSurface> default_offscreen_surface,
- gpu::SyncPointManager* sync_point_manager,
- gpu::SharedImageManager* shared_image_manager,
- gpu::Scheduler* scheduler,
- base::WaitableEvent* shutdown_event) {
- DCHECK(main_runner_->BelongsToCurrentThread());
-
- mojo::Remote<mojom::GpuHost> gpu_host(std::move(pending_gpu_host));
- gpu_host->DidInitialize(gpu_info_, gpu_feature_info_,
- gpu_info_for_hardware_gpu_,
- gpu_feature_info_for_hardware_gpu_, gpu_extra_info_);
- ……
- }
由于gpu_info_是GpuServiceImpl类的成员变量(components/viz/service/gl/gpu_service_impl.h中定义):
- // Information about the GPU, such as device and vendor ID.
- gpu::GPUInfo gpu_info_;
因此能够推测,很有可能是在GpuServiceImpl的构造函数中传入的。为了印证这一推测,在Chromium源码路径下搜索创建GpuServiceImpl类的对象的相关代码。结果发现结果太多了(一共2、300处,过滤之后也有小100处),因此决定不走这条路,而走另外一条路,即在Chromium源码路径下搜索与以下函数相关的内容。
- void GpuServiceImpl::UpdateGPUInfoGL() {
- DCHECK(main_runner_->BelongsToCurrentThread());
- gpu::CollectGraphicsInfoGL(&gpu_info_, GetContextState()->display());
- gpu_host_->DidUpdateGPUInfo(gpu_info_);
- }
果然少多了,只有几处而已。这样就很便于分析问题了。下一回将深入解析这些相关代码。
至于本回,在结束之前,还要说明一下:虽然上边由于搜索创建GpuServiceImpl对象的相关代码的结果太多而放弃,但是推测倒是被印证了。因为GpuServiceImpl类的构造函数本身就已说明了问题。在components/viz/service/gl/gpu_service_impl.cc中,代码如下:
- GpuServiceImpl::GpuServiceImpl(
- const gpu::GPUInfo& gpu_info,
- std::unique_ptr<gpu::GpuWatchdogThread> watchdog_thread,
- scoped_refptr<base::SingleThreadTaskRunner> io_runner,
- const gpu::GpuFeatureInfo& gpu_feature_info,
- const gpu::GpuPreferences& gpu_preferences,
- const absl::optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu,
- const absl::optional<gpu::GpuFeatureInfo>&
- gpu_feature_info_for_hardware_gpu,
- const gfx::GpuExtraInfo& gpu_extra_info,
- gpu::VulkanImplementation* vulkan_implementation,
- base::OnceCallback<void(ExitCode)> exit_callback)
- : main_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()),
- io_runner_(std::move(io_runner)),
- watchdog_thread_(std::move(watchdog_thread)),
- gpu_preferences_(gpu_preferences),
- gpu_info_(gpu_info),
- gpu_feature_info_(gpu_feature_info),
- gpu_driver_bug_workarounds_(
- gpu_feature_info.enabled_gpu_driver_bug_workarounds),
- gpu_info_for_hardware_gpu_(gpu_info_for_hardware_gpu),
- gpu_feature_info_for_hardware_gpu_(gpu_feature_info_for_hardware_gpu),
- gpu_extra_info_(gpu_extra_info),
- #if BUILDFLAG(ENABLE_VULKAN)
- vulkan_implementation_(vulkan_implementation),
- #endif
- exit_callback_(std::move(exit_callback)) {
- DCHECK(!io_runner_->BelongsToCurrentThread());
- DCHECK(exit_callback_);
-
- #if BUILDFLAG(IS_CHROMEOS_ASH) && BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
- protected_buffer_manager_ = new arc::ProtectedBufferManager();
- #endif // BUILDFLAG(IS_CHROMEOS_ASH) &&
- // BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
-
- GrContextOptions context_options =
- GetDefaultGrContextOptions(gpu_preferences_.gr_context_type);
- if (gpu_preferences_.force_max_texture_size) {
- context_options.fMaxTextureSizeOverride =
- gpu_preferences_.force_max_texture_size;
- }
-
- #if BUILDFLAG(ENABLE_VULKAN)
- if (vulkan_implementation_) {
- bool is_native_vulkan =
- gpu_preferences_.use_vulkan == gpu::VulkanImplementationName::kNative ||
- gpu_preferences_.use_vulkan ==
- gpu::VulkanImplementationName::kForcedNative;
- // With swiftshader the vendor_id is 0xffff. For some tests gpu_info is not
- // initialized, so the vendor_id is 0.
- bool is_native_gl =
- gpu_info_.gpu.vendor_id != 0xffff && gpu_info_.gpu.vendor_id != 0;
-
- const bool is_thread_safe =
- features::IsDrDcEnabled() && !gpu_driver_bug_workarounds_.disable_drdc;
- // If GL is using a real GPU, the gpu_info will be passed in and vulkan will
- // use the same GPU.
- vulkan_context_provider_ = VulkanInProcessContextProvider::Create(
- vulkan_implementation_, gpu_preferences_.vulkan_heap_memory_limit,
- gpu_preferences_.vulkan_sync_cpu_memory_limit, is_thread_safe,
- (is_native_vulkan && is_native_gl) ? &gpu_info : nullptr);
- if (!vulkan_context_provider_) {
- DLOG(ERROR) << "Failed to create Vulkan context provider.";
- }
- }
- #endif
-
- #if BUILDFLAG(SKIA_USE_DAWN)
- if (gpu_preferences_.gr_context_type == gpu::GrContextType::kDawn) {
- dawn_context_provider_ = DawnContextProvider::Create();
- if (!dawn_context_provider_) {
- DLOG(ERROR) << "Failed to create Dawn context provider.";
- }
- }
- #endif
-
- #if BUILDFLAG(USE_VAAPI_IMAGE_CODECS)
- image_decode_accelerator_worker_ =
- media::VaapiImageDecodeAcceleratorWorker::Create();
- #endif // BUILDFLAG(USE_VAAPI_IMAGE_CODECS)
-
- #if BUILDFLAG(IS_APPLE)
- if (gpu_feature_info_.status_values[gpu::GPU_FEATURE_TYPE_METAL] ==
- gpu::kGpuFeatureStatusEnabled) {
- metal_context_provider_ = MetalContextProvider::Create(context_options);
- }
- #endif
-
- #if BUILDFLAG(IS_WIN)
- if (media::SupportMediaFoundationClearPlayback()) {
- // Initialize the OverlayStateService using the GPUServiceImpl task
- // sequence.
- auto* overlay_state_service = OverlayStateService::GetInstance();
- overlay_state_service->Initialize(
- base::SequencedTaskRunner::GetCurrentDefault());
- }
-
- // Add GpuServiceImpl to DirectCompositionOverlayCapsMonitor observer list for
- // overlay and DXGI info update.
- gl::DirectCompositionOverlayCapsMonitor::GetInstance()->AddObserver(this);
- #endif
-
- gpu_memory_buffer_factory_ = gpu::GpuMemoryBufferFactory::CreateNativeType(
- vulkan_context_provider(), io_runner_);
-
- weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
- }
看到以下代码片段了吧:
- GpuServiceImpl::GpuServiceImpl(
- const gpu::GPUInfo& gpu_info,
- std::unique_ptr<gpu::GpuWatchdogThread> watchdog_thread,
- scoped_refptr<base::SingleThreadTaskRunner> io_runner,
- const gpu::GpuFeatureInfo& gpu_feature_info,
- const gpu::GpuPreferences& gpu_preferences,
- const absl::optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu,
- const absl::optional<gpu::GpuFeatureInfo>&
- gpu_feature_info_for_hardware_gpu,
- const gfx::GpuExtraInfo& gpu_extra_info,
- gpu::VulkanImplementation* vulkan_implementation,
- base::OnceCallback<void(ExitCode)> exit_callback)
- : main_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()),
- io_runner_(std::move(io_runner)),
- watchdog_thread_(std::move(watchdog_thread)),
- gpu_preferences_(gpu_preferences),
- gpu_info_(gpu_info),
- ……
- }
这就说明在构造GpuServiceImpl类对象的时候,gpu_info参数就是由调用者传入的,进而赋给了gpu_info_。这个分支等将来对于Chromium代码更加熟悉了,再回过头来研究。
欲知后事如何,且看下回分解。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。