gpuinfo_manager.cc 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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 "atom/browser/api/gpuinfo_manager.h"
  5. #include <utility>
  6. #include "atom/browser/api/gpu_info_enumerator.h"
  7. #include "base/memory/singleton.h"
  8. #include "base/threading/thread_task_runner_handle.h"
  9. #include "content/public/browser/browser_thread.h"
  10. #include "gpu/config/gpu_info_collector.h"
  11. namespace atom {
  12. GPUInfoManager* GPUInfoManager::GetInstance() {
  13. return base::Singleton<GPUInfoManager>::get();
  14. }
  15. GPUInfoManager::GPUInfoManager()
  16. : gpu_data_manager_(content::GpuDataManagerImpl::GetInstance()) {
  17. gpu_data_manager_->AddObserver(this);
  18. }
  19. GPUInfoManager::~GPUInfoManager() {
  20. content::GpuDataManagerImpl::GetInstance()->RemoveObserver(this);
  21. }
  22. // Based on
  23. // https://chromium.googlesource.com/chromium/src.git/+/69.0.3497.106/content/browser/gpu/gpu_data_manager_impl_private.cc#838
  24. bool GPUInfoManager::NeedsCompleteGpuInfoCollection() const {
  25. #if defined(OS_MACOSX)
  26. return gpu_data_manager_->GetGPUInfo().gl_vendor.empty();
  27. #elif defined(OS_WIN)
  28. return (gpu_data_manager_->GetGPUInfo().dx_diagnostics.values.empty() &&
  29. gpu_data_manager_->GetGPUInfo().dx_diagnostics.children.empty());
  30. #else
  31. return false;
  32. #endif
  33. }
  34. // Should be posted to the task runner
  35. void GPUInfoManager::ProcessCompleteInfo() {
  36. const auto result = EnumerateGPUInfo(gpu_data_manager_->GetGPUInfo());
  37. // We have received the complete information, resolve all promises that
  38. // were waiting for this info.
  39. for (auto& promise : complete_info_promise_set_) {
  40. promise.Resolve(*result);
  41. }
  42. complete_info_promise_set_.clear();
  43. }
  44. void GPUInfoManager::OnGpuInfoUpdate() {
  45. // Ignore if called when not asked for complete GPUInfo
  46. if (NeedsCompleteGpuInfoCollection())
  47. return;
  48. base::ThreadTaskRunnerHandle::Get()->PostTask(
  49. FROM_HERE, base::BindOnce(&GPUInfoManager::ProcessCompleteInfo,
  50. base::Unretained(this)));
  51. }
  52. // Should be posted to the task runner
  53. void GPUInfoManager::CompleteInfoFetcher(util::Promise promise) {
  54. complete_info_promise_set_.emplace_back(std::move(promise));
  55. if (NeedsCompleteGpuInfoCollection()) {
  56. gpu_data_manager_->RequestCompleteGpuInfoIfNeeded();
  57. } else {
  58. GPUInfoManager::OnGpuInfoUpdate();
  59. }
  60. }
  61. void GPUInfoManager::FetchCompleteInfo(util::Promise promise) {
  62. base::ThreadTaskRunnerHandle::Get()->PostTask(
  63. FROM_HERE, base::BindOnce(&GPUInfoManager::CompleteInfoFetcher,
  64. base::Unretained(this), std::move(promise)));
  65. }
  66. // This fetches the info synchronously, so no need to post to the task queue.
  67. // There cannot be multiple promises as they are resolved synchronously.
  68. void GPUInfoManager::FetchBasicInfo(util::Promise promise) {
  69. gpu::GPUInfo gpu_info;
  70. CollectBasicGraphicsInfo(&gpu_info);
  71. promise.Resolve(*EnumerateGPUInfo(gpu_info));
  72. }
  73. std::unique_ptr<base::DictionaryValue> GPUInfoManager::EnumerateGPUInfo(
  74. gpu::GPUInfo gpu_info) const {
  75. GPUInfoEnumerator enumerator;
  76. gpu_info.EnumerateFields(&enumerator);
  77. return enumerator.GetDictionary();
  78. }
  79. } // namespace atom