gpuinfo_manager.cc 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Copyright (c) 2018 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "shell/browser/api/gpuinfo_manager.h"
  5. #include <utility>
  6. #include "base/memory/singleton.h"
  7. #include "base/task/single_thread_task_runner.h"
  8. #include "content/public/browser/browser_thread.h"
  9. #include "gpu/config/gpu_info_collector.h"
  10. #include "shell/browser/api/gpu_info_enumerator.h"
  11. #include "shell/common/gin_converters/value_converter.h"
  12. namespace electron {
  13. GPUInfoManager* GPUInfoManager::GetInstance() {
  14. return base::Singleton<GPUInfoManager>::get();
  15. }
  16. GPUInfoManager::GPUInfoManager()
  17. : gpu_data_manager_(content::GpuDataManagerImpl::GetInstance()) {
  18. gpu_data_manager_->AddObserver(this);
  19. }
  20. GPUInfoManager::~GPUInfoManager() {
  21. content::GpuDataManagerImpl::GetInstance()->RemoveObserver(this);
  22. }
  23. // Based on
  24. // https://chromium.googlesource.com/chromium/src.git/+/69.0.3497.106/content/browser/gpu/gpu_data_manager_impl_private.cc#838
  25. bool GPUInfoManager::NeedsCompleteGpuInfoCollection() const {
  26. #if BUILDFLAG(IS_WIN)
  27. return gpu_data_manager_->DxdiagDx12VulkanRequested() &&
  28. gpu_data_manager_->GetGPUInfo().dx_diagnostics.IsEmpty();
  29. #else
  30. return false;
  31. #endif
  32. }
  33. // Should be posted to the task runner
  34. void GPUInfoManager::ProcessCompleteInfo() {
  35. base::Value::Dict result = EnumerateGPUInfo(gpu_data_manager_->GetGPUInfo());
  36. // We have received the complete information, resolve all promises that
  37. // were waiting for this info.
  38. for (auto& promise : complete_info_promise_set_) {
  39. promise.Resolve(base::Value(result.Clone()));
  40. }
  41. complete_info_promise_set_.clear();
  42. }
  43. void GPUInfoManager::OnGpuInfoUpdate() {
  44. // Ignore if called when not asked for complete GPUInfo
  45. if (NeedsCompleteGpuInfoCollection())
  46. return;
  47. base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
  48. FROM_HERE, base::BindOnce(&GPUInfoManager::ProcessCompleteInfo,
  49. base::Unretained(this)));
  50. }
  51. // Should be posted to the task runner
  52. void GPUInfoManager::CompleteInfoFetcher(
  53. gin_helper::Promise<base::Value> promise) {
  54. complete_info_promise_set_.emplace_back(std::move(promise));
  55. if (NeedsCompleteGpuInfoCollection()) {
  56. gpu_data_manager_->RequestDxdiagDx12VulkanVideoGpuInfoIfNeeded(
  57. content::GpuDataManagerImpl::kGpuInfoRequestAll, /* delayed */ false);
  58. } else {
  59. GPUInfoManager::OnGpuInfoUpdate();
  60. }
  61. }
  62. void GPUInfoManager::FetchCompleteInfo(
  63. gin_helper::Promise<base::Value> promise) {
  64. base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
  65. FROM_HERE, base::BindOnce(&GPUInfoManager::CompleteInfoFetcher,
  66. base::Unretained(this), std::move(promise)));
  67. }
  68. // This fetches the info synchronously, so no need to post to the task queue.
  69. // There cannot be multiple promises as they are resolved synchronously.
  70. void GPUInfoManager::FetchBasicInfo(gin_helper::Promise<base::Value> promise) {
  71. gpu::GPUInfo gpu_info;
  72. CollectBasicGraphicsInfo(&gpu_info);
  73. promise.Resolve(base::Value(EnumerateGPUInfo(gpu_info)));
  74. }
  75. base::Value::Dict GPUInfoManager::EnumerateGPUInfo(
  76. gpu::GPUInfo gpu_info) const {
  77. GPUInfoEnumerator enumerator;
  78. gpu_info.EnumerateFields(&enumerator);
  79. return enumerator.GetDictionary();
  80. }
  81. } // namespace electron