Chromium源码由浅入深(五)

编程入门 行业动态 更新时间:2024-10-19 04:27:18

Chromium源码<a href=https://www.elefans.com/category/jswz/34/1744432.html style=由浅入深(五)"/>

Chromium源码由浅入深(五)

接前一篇文章:Chromium源码由浅入深(四)

上回书一步步跟踪,最终跟踪到components/viz/service/gl/gpu_service_impl中相邻的两个函数(方法),分别是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();
#endifowned_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 threadpositor_gpu_thread_ = CompositorGpuThread::Create(gpu_channel_manager_.get(),
#if BUILDFLAG(ENABLE_VULKAN)vulkan_implementation_,vulkan_context_provider_ ? vulkan_context_provider_->GetDeviceQueue(): nullptr,
#elsenullptr, nullptr,
#endifgpu_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中,代码分别如下:

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中,代码如下:

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),
#endifexit_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);
#endifgpu_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代码更加熟悉了,再回过头来研究。

欲知后事如何,且看下回分解。

更多推荐

Chromium源码由浅入深(五)

本文发布于:2023-12-03 08:30:26,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1653233.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:由浅入深   源码   Chromium

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!