recyclable_compositor_mac.cc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // Copyright 2018 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 "ui/compositor/recyclable_compositor_mac.h"
  5. #include "base/bind.h"
  6. #include "base/no_destructor.h"
  7. #include "base/threading/thread_task_runner_handle.h"
  8. #include "components/viz/common/features.h"
  9. #include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
  10. #include "ui/compositor/compositor.h"
  11. #include "ui/compositor/compositor_observer.h"
  12. #include "ui/compositor/compositor_switches.h"
  13. namespace ui {
  14. namespace {
  15. // Returns a task runner for creating a ui::Compositor. This allows compositor
  16. // tasks to be funneled through ui::WindowResizeHelper's task runner to allow
  17. // resize operations to coordinate with frames provided by the GPU process.
  18. scoped_refptr<base::SingleThreadTaskRunner> GetCompositorTaskRunner() {
  19. // If the WindowResizeHelper's pumpable task runner is set, it means the GPU
  20. // process is directing messages there, and the compositor can synchronize
  21. // with it. Otherwise, just use the UI thread.
  22. scoped_refptr<base::SingleThreadTaskRunner> task_runner =
  23. ui::WindowResizeHelperMac::Get()->task_runner();
  24. return task_runner ? task_runner : base::ThreadTaskRunnerHandle::Get();
  25. }
  26. } // namespace
  27. ////////////////////////////////////////////////////////////////////////////////
  28. // RecyclableCompositorMac
  29. RecyclableCompositorMac::RecyclableCompositorMac(
  30. ui::ContextFactory* context_factory)
  31. : accelerated_widget_mac_(new ui::AcceleratedWidgetMac()),
  32. compositor_(context_factory->AllocateFrameSinkId(),
  33. context_factory,
  34. GetCompositorTaskRunner(),
  35. ui::IsPixelCanvasRecordingEnabled()) {
  36. compositor_.SetAcceleratedWidget(
  37. accelerated_widget_mac_->accelerated_widget());
  38. Suspend();
  39. compositor_.AddObserver(this);
  40. }
  41. RecyclableCompositorMac::~RecyclableCompositorMac() {
  42. compositor_.RemoveObserver(this);
  43. }
  44. void RecyclableCompositorMac::Suspend() {
  45. // Requests a compositor lock without a timeout.
  46. compositor_suspended_lock_ =
  47. compositor_.GetCompositorLock(nullptr, base::TimeDelta());
  48. }
  49. void RecyclableCompositorMac::Unsuspend() {
  50. compositor_suspended_lock_ = nullptr;
  51. }
  52. void RecyclableCompositorMac::UpdateSurface(
  53. const gfx::Size& size_pixels,
  54. float scale_factor,
  55. const gfx::DisplayColorSpaces& display_color_spaces) {
  56. if (size_pixels != size_pixels_ || scale_factor != scale_factor_) {
  57. size_pixels_ = size_pixels;
  58. scale_factor_ = scale_factor;
  59. local_surface_id_allocator_.GenerateId();
  60. viz::LocalSurfaceId local_surface_id =
  61. local_surface_id_allocator_.GetCurrentLocalSurfaceId();
  62. compositor()->SetScaleAndSize(scale_factor_, size_pixels_,
  63. local_surface_id);
  64. }
  65. if (display_color_spaces != display_color_spaces_) {
  66. display_color_spaces_ = display_color_spaces;
  67. compositor()->SetDisplayColorSpaces(display_color_spaces_);
  68. }
  69. }
  70. void RecyclableCompositorMac::InvalidateSurface() {
  71. size_pixels_ = gfx::Size();
  72. scale_factor_ = 1.f;
  73. local_surface_id_allocator_.Invalidate();
  74. display_color_spaces_ = gfx::DisplayColorSpaces();
  75. compositor()->SetScaleAndSize(
  76. scale_factor_, size_pixels_,
  77. local_surface_id_allocator_.GetCurrentLocalSurfaceId());
  78. compositor()->SetDisplayColorSpaces(gfx::DisplayColorSpaces());
  79. }
  80. void RecyclableCompositorMac::OnCompositingDidCommit(
  81. ui::Compositor* compositor_that_did_commit) {
  82. DCHECK_EQ(compositor_that_did_commit, compositor());
  83. accelerated_widget_mac_->SetSuspended(false);
  84. }
  85. } // namespace ui