layer_tree_frame_sink_holder.cc 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // Copyright 2016 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 "components/exo/layer_tree_frame_sink_holder.h"
  5. #include "base/containers/contains.h"
  6. #include "base/threading/thread_task_runner_handle.h"
  7. #include "cc/trees/layer_tree_frame_sink.h"
  8. #include "components/exo/surface_tree_host.h"
  9. #include "components/viz/common/frame_timing_details.h"
  10. #include "components/viz/common/hit_test/hit_test_region_list.h"
  11. #include "components/viz/common/resources/returned_resource.h"
  12. namespace exo {
  13. ////////////////////////////////////////////////////////////////////////////////
  14. // LayerTreeFrameSinkHolder, public:
  15. LayerTreeFrameSinkHolder::LayerTreeFrameSinkHolder(
  16. SurfaceTreeHost* surface_tree_host,
  17. std::unique_ptr<cc::LayerTreeFrameSink> frame_sink)
  18. : surface_tree_host_(surface_tree_host),
  19. frame_sink_(std::move(frame_sink)) {
  20. frame_sink_->BindToClient(this);
  21. }
  22. LayerTreeFrameSinkHolder::~LayerTreeFrameSinkHolder() {
  23. if (frame_sink_)
  24. frame_sink_->DetachFromClient();
  25. if (lifetime_manager_)
  26. lifetime_manager_->RemoveObserver(this);
  27. }
  28. // static
  29. void LayerTreeFrameSinkHolder::DeleteWhenLastResourceHasBeenReclaimed(
  30. std::unique_ptr<LayerTreeFrameSinkHolder> holder) {
  31. // Delete immediately if LayerTreeFrameSink was already lost.
  32. if (holder->is_lost_)
  33. return;
  34. if (holder->last_frame_size_in_pixels_.IsEmpty()) {
  35. // Delete sink holder immediately if no frame has been submitted.
  36. DCHECK(holder->last_frame_resources_.empty());
  37. return;
  38. }
  39. // Submit an empty frame to ensure that pending release callbacks will be
  40. // processed in a finite amount of time.
  41. viz::CompositorFrame frame;
  42. frame.metadata.begin_frame_ack.frame_id =
  43. viz::BeginFrameId(viz::BeginFrameArgs::kManualSourceId,
  44. viz::BeginFrameArgs::kStartingFrameNumber);
  45. frame.metadata.begin_frame_ack.has_damage = true;
  46. frame.metadata.frame_token = ++holder->next_frame_token_;
  47. frame.metadata.device_scale_factor = holder->last_frame_device_scale_factor_;
  48. auto pass = viz::CompositorRenderPass::Create();
  49. pass->SetNew(viz::CompositorRenderPassId{1},
  50. gfx::Rect(holder->last_frame_size_in_pixels_),
  51. gfx::Rect(holder->last_frame_size_in_pixels_), gfx::Transform());
  52. frame.render_pass_list.push_back(std::move(pass));
  53. holder->last_frame_resources_.clear();
  54. holder->frame_sink_->SubmitCompositorFrame(std::move(frame),
  55. /*hit_test_data_changed=*/true);
  56. // Delete sink holder immediately if not waiting for resources to be
  57. // reclaimed.
  58. if (holder->resource_manager_.HasNoCallbacks())
  59. return;
  60. WMHelper::LifetimeManager* lifetime_manager =
  61. WMHelper::GetInstance()->GetLifetimeManager();
  62. holder->lifetime_manager_ = lifetime_manager;
  63. holder->surface_tree_host_ = nullptr;
  64. // If we have pending release callbacks then extend the lifetime of holder
  65. // by adding it as a LifetimeManager observer. The holder will delete itself
  66. // when LifetimeManager shuts down or when all pending release callbacks have
  67. // been called.
  68. lifetime_manager->AddObserver(holder.release());
  69. }
  70. void LayerTreeFrameSinkHolder::SubmitCompositorFrame(
  71. viz::CompositorFrame frame) {
  72. DCHECK(!is_lost_);
  73. last_frame_size_in_pixels_ = frame.size_in_pixels();
  74. last_frame_device_scale_factor_ = frame.metadata.device_scale_factor;
  75. last_frame_resources_.clear();
  76. for (auto& resource : frame.resource_list)
  77. last_frame_resources_.push_back(resource.id);
  78. frame_sink_->SubmitCompositorFrame(std::move(frame),
  79. /*hit_test_data_changed=*/true);
  80. }
  81. void LayerTreeFrameSinkHolder::DidNotProduceFrame(
  82. const viz::BeginFrameAck& ack) {
  83. DCHECK(!is_lost_);
  84. frame_sink_->DidNotProduceFrame(ack, cc::FrameSkippedReason::kNoDamage);
  85. }
  86. ////////////////////////////////////////////////////////////////////////////////
  87. // cc::LayerTreeFrameSinkClient overrides:
  88. absl::optional<viz::HitTestRegionList>
  89. LayerTreeFrameSinkHolder::BuildHitTestData() {
  90. return {};
  91. }
  92. void LayerTreeFrameSinkHolder::ReclaimResources(
  93. std::vector<viz::ReturnedResource> resources) {
  94. for (auto& resource : resources) {
  95. // Skip resources that are also in last frame. This can happen if
  96. // the frame sink id changed.
  97. if (base::Contains(last_frame_resources_, resource.id)) {
  98. continue;
  99. }
  100. resource_manager_.ReclaimResource(std::move(resource));
  101. }
  102. if (lifetime_manager_ && resource_manager_.HasNoCallbacks())
  103. ScheduleDelete();
  104. }
  105. void LayerTreeFrameSinkHolder::DidReceiveCompositorFrameAck() {
  106. if (surface_tree_host_)
  107. surface_tree_host_->DidReceiveCompositorFrameAck();
  108. }
  109. void LayerTreeFrameSinkHolder::DidPresentCompositorFrame(
  110. uint32_t frame_token,
  111. const viz::FrameTimingDetails& details) {
  112. if (surface_tree_host_) {
  113. surface_tree_host_->DidPresentCompositorFrame(
  114. frame_token, details.presentation_feedback);
  115. }
  116. }
  117. void LayerTreeFrameSinkHolder::DidLoseLayerTreeFrameSink() {
  118. last_frame_resources_.clear();
  119. resource_manager_.ClearAllCallbacks();
  120. is_lost_ = true;
  121. if (lifetime_manager_)
  122. ScheduleDelete();
  123. }
  124. ////////////////////////////////////////////////////////////////////////////////
  125. // LayerTreeFrameSinkHolder, private:
  126. void LayerTreeFrameSinkHolder::ScheduleDelete() {
  127. if (delete_pending_)
  128. return;
  129. delete_pending_ = true;
  130. base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
  131. }
  132. void LayerTreeFrameSinkHolder::OnDestroyed() {
  133. lifetime_manager_->RemoveObserver(this);
  134. lifetime_manager_ = nullptr;
  135. // Make sure frame sink never outlives the shell.
  136. frame_sink_->DetachFromClient();
  137. frame_sink_.reset();
  138. ScheduleDelete();
  139. }
  140. } // namespace exo