gpuinfo_manager.cc 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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/threading/thread_task_runner_handle.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 defined(OS_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. const auto 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(*result);
  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::ThreadTaskRunnerHandle::Get()->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::DictionaryValue> 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::DictionaryValue> promise) {
  64. base::ThreadTaskRunnerHandle::Get()->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(
  71. gin_helper::Promise<base::DictionaryValue> promise) {
  72. gpu::GPUInfo gpu_info;
  73. CollectBasicGraphicsInfo(&gpu_info);
  74. promise.Resolve(*EnumerateGPUInfo(gpu_info));
  75. }
  76. std::unique_ptr<base::DictionaryValue> GPUInfoManager::EnumerateGPUInfo(
  77. gpu::GPUInfo gpu_info) const {
  78. GPUInfoEnumerator enumerator;
  79. gpu_info.EnumerateFields(&enumerator);
  80. return enumerator.GetDictionary();
  81. }
  82. } // namespace electron