ash_display_util.cc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "remoting/host/chromeos/ash_display_util.h"
  5. #include "ash/shell.h"
  6. #include "base/no_destructor.h"
  7. #include "components/viz/common/frame_sinks/copy_output_request.h"
  8. #include "remoting/base/constants.h"
  9. #include "ui/compositor/layer.h"
  10. #include "ui/display/manager/display_manager.h"
  11. #include "ui/display/screen.h"
  12. #include "ui/display/types/display_constants.h"
  13. namespace remoting {
  14. namespace {
  15. absl::optional<SkBitmap> ToSkBitmap(
  16. std::unique_ptr<viz::CopyOutputResult> result) {
  17. if (result->IsEmpty())
  18. return absl::nullopt;
  19. auto scoped_bitmap = result->ScopedAccessSkBitmap();
  20. return scoped_bitmap.GetOutScopedBitmap();
  21. }
  22. class DefaultAshDisplayUtil : public AshDisplayUtil {
  23. public:
  24. DefaultAshDisplayUtil() = default;
  25. DefaultAshDisplayUtil(const DefaultAshDisplayUtil&) = delete;
  26. DefaultAshDisplayUtil& operator=(const DefaultAshDisplayUtil&) = delete;
  27. ~DefaultAshDisplayUtil() override = default;
  28. // AshDisplayUtil implementation:
  29. DisplayId GetPrimaryDisplayId() const override {
  30. if (!screen())
  31. return display::kDefaultDisplayId;
  32. return screen()->GetPrimaryDisplay().id();
  33. }
  34. const std::vector<display::Display>& GetActiveDisplays() const override {
  35. return display_manager().active_display_list();
  36. }
  37. const display::Display* GetDisplayForId(DisplayId display_id) const override {
  38. if (!display_manager().IsActiveDisplayId(display_id))
  39. return nullptr;
  40. return &display_manager().GetDisplayForId(display_id);
  41. }
  42. void TakeScreenshotOfDisplay(DisplayId display_id,
  43. ScreenshotCallback callback) override {
  44. aura::Window* root_window = GetRootWindowForId(display_id);
  45. if (!root_window) {
  46. std::move(callback).Run(absl::nullopt);
  47. return;
  48. }
  49. auto request = std::make_unique<viz::CopyOutputRequest>(
  50. viz::CopyOutputRequest::ResultFormat::RGBA,
  51. viz::CopyOutputRequest::ResultDestination::kSystemMemory,
  52. base::BindOnce(&ToSkBitmap).Then(std::move(callback)));
  53. request->set_area(gfx::Rect(root_window->bounds().size()));
  54. root_window->layer()->RequestCopyOfOutput(std::move(request));
  55. }
  56. private:
  57. const display::Screen* screen() const { return display::Screen::GetScreen(); }
  58. // We can not return a const reference, as the ash shell has no const getter
  59. // for the display manager :/
  60. ash::Shell& shell() const {
  61. auto* shell = ash::Shell::Get();
  62. DCHECK(shell);
  63. return *shell;
  64. }
  65. const display::DisplayManager& display_manager() const {
  66. const auto* result = shell().display_manager();
  67. DCHECK(result);
  68. return *result;
  69. }
  70. aura::Window* GetRootWindowForId(DisplayId id) {
  71. return shell().GetRootWindowForDisplayId(id);
  72. }
  73. };
  74. AshDisplayUtil* g_instance_for_testing_ = nullptr;
  75. } // namespace
  76. // static
  77. AshDisplayUtil& AshDisplayUtil::Get() {
  78. static base::NoDestructor<DefaultAshDisplayUtil> instance_;
  79. if (g_instance_for_testing_)
  80. return *g_instance_for_testing_;
  81. return *instance_;
  82. }
  83. // static
  84. void AshDisplayUtil::SetInstanceForTesting(AshDisplayUtil* instance) {
  85. if (instance)
  86. DCHECK(!g_instance_for_testing_);
  87. g_instance_for_testing_ = instance;
  88. }
  89. // static
  90. int AshDisplayUtil::ScaleFactorToDpi(float scale_factor) {
  91. return static_cast<int>(scale_factor * kDefaultDpi);
  92. }
  93. // static
  94. int AshDisplayUtil::GetDpi(const display::Display& display) {
  95. return ScaleFactorToDpi(display.device_scale_factor());
  96. }
  97. AshDisplayUtil::~AshDisplayUtil() = default;
  98. } // namespace remoting