direct_layer_tree_frame_sink.cc 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. // Copyright 2014 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/test/direct_layer_tree_frame_sink.h"
  5. #include <memory>
  6. #include "base/bind.h"
  7. #include "base/compiler_specific.h"
  8. #include "base/trace_event/trace_event.h"
  9. #include "build/build_config.h"
  10. #include "cc/trees/layer_tree_frame_sink_client.h"
  11. #include "components/viz/common/hit_test/hit_test_region_list.h"
  12. #include "components/viz/common/quads/compositor_frame.h"
  13. #include "components/viz/common/surfaces/frame_sink_id.h"
  14. #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
  15. #include "components/viz/service/display/display.h"
  16. #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
  17. #include "components/viz/service/surfaces/surface.h"
  18. namespace ui {
  19. DirectLayerTreeFrameSink::DirectLayerTreeFrameSink(
  20. const viz::FrameSinkId& frame_sink_id,
  21. viz::FrameSinkManagerImpl* frame_sink_manager,
  22. viz::Display* display,
  23. scoped_refptr<viz::ContextProvider> context_provider,
  24. scoped_refptr<viz::RasterContextProvider> worker_context_provider,
  25. scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
  26. gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager)
  27. : LayerTreeFrameSink(std::move(context_provider),
  28. std::move(worker_context_provider),
  29. std::move(compositor_task_runner),
  30. gpu_memory_buffer_manager),
  31. frame_sink_id_(frame_sink_id),
  32. frame_sink_manager_(frame_sink_manager),
  33. display_(display) {
  34. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  35. }
  36. DirectLayerTreeFrameSink::~DirectLayerTreeFrameSink() {
  37. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  38. }
  39. bool DirectLayerTreeFrameSink::BindToClient(
  40. cc::LayerTreeFrameSinkClient* client) {
  41. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  42. if (!cc::LayerTreeFrameSink::BindToClient(client))
  43. return false;
  44. support_ = std::make_unique<viz::CompositorFrameSinkSupport>(
  45. this, frame_sink_manager_, frame_sink_id_, /*is_root=*/true);
  46. begin_frame_source_ = std::make_unique<viz::ExternalBeginFrameSource>(this);
  47. client_->SetBeginFrameSource(begin_frame_source_.get());
  48. // Avoid initializing GL context here, as this should be sharing the
  49. // Display's context.
  50. display_->Initialize(this, frame_sink_manager_->surface_manager());
  51. support_->SetUpHitTest(display_);
  52. return true;
  53. }
  54. void DirectLayerTreeFrameSink::DetachFromClient() {
  55. client_->SetBeginFrameSource(nullptr);
  56. begin_frame_source_.reset();
  57. // Unregister the SurfaceFactoryClient here instead of the dtor so that only
  58. // one client is alive for this namespace at any given time.
  59. support_.reset();
  60. cc::LayerTreeFrameSink::DetachFromClient();
  61. }
  62. void DirectLayerTreeFrameSink::SubmitCompositorFrame(
  63. viz::CompositorFrame frame,
  64. bool hit_test_data_changed) {
  65. DCHECK(frame.metadata.begin_frame_ack.has_damage);
  66. DCHECK(frame.metadata.begin_frame_ack.frame_id.IsSequenceValid());
  67. if (frame.size_in_pixels() != last_swap_frame_size_ ||
  68. frame.device_scale_factor() != device_scale_factor_ ||
  69. !parent_local_surface_id_allocator_.HasValidLocalSurfaceId()) {
  70. parent_local_surface_id_allocator_.GenerateId();
  71. last_swap_frame_size_ = frame.size_in_pixels();
  72. device_scale_factor_ = frame.device_scale_factor();
  73. display_->SetLocalSurfaceId(
  74. parent_local_surface_id_allocator_.GetCurrentLocalSurfaceId(),
  75. device_scale_factor_);
  76. }
  77. absl::optional<viz::HitTestRegionList> hit_test_region_list =
  78. client_->BuildHitTestData();
  79. if (!hit_test_region_list) {
  80. last_hit_test_data_ = viz::HitTestRegionList();
  81. } else if (!hit_test_data_changed) {
  82. // Do not send duplicate hit-test data.
  83. if (viz::HitTestRegionList::IsEqual(*hit_test_region_list,
  84. last_hit_test_data_)) {
  85. DCHECK(!viz::HitTestRegionList::IsEqual(*hit_test_region_list,
  86. viz::HitTestRegionList()));
  87. hit_test_region_list = absl::nullopt;
  88. } else {
  89. last_hit_test_data_ = *hit_test_region_list;
  90. }
  91. } else {
  92. last_hit_test_data_ = *hit_test_region_list;
  93. }
  94. support_->SubmitCompositorFrame(
  95. parent_local_surface_id_allocator_.GetCurrentLocalSurfaceId(),
  96. std::move(frame), std::move(hit_test_region_list));
  97. }
  98. void DirectLayerTreeFrameSink::DidNotProduceFrame(
  99. const viz::BeginFrameAck& ack,
  100. cc::FrameSkippedReason reason) {
  101. DCHECK(!ack.has_damage);
  102. DCHECK(ack.frame_id.IsSequenceValid());
  103. support_->DidNotProduceFrame(ack);
  104. }
  105. void DirectLayerTreeFrameSink::DidAllocateSharedBitmap(
  106. base::ReadOnlySharedMemoryRegion region,
  107. const viz::SharedBitmapId& id) {
  108. bool ok = support_->DidAllocateSharedBitmap(std::move(region), id);
  109. DCHECK(ok);
  110. }
  111. void DirectLayerTreeFrameSink::DidDeleteSharedBitmap(
  112. const viz::SharedBitmapId& id) {
  113. support_->DidDeleteSharedBitmap(id);
  114. }
  115. void DirectLayerTreeFrameSink::DisplayOutputSurfaceLost() {
  116. is_lost_ = true;
  117. client_->DidLoseLayerTreeFrameSink();
  118. }
  119. void DirectLayerTreeFrameSink::DisplayWillDrawAndSwap(
  120. bool will_draw_and_swap,
  121. viz::AggregatedRenderPassList* render_passes) {
  122. if (support_->GetHitTestAggregator()) {
  123. support_->GetHitTestAggregator()->Aggregate(display_->CurrentSurfaceId());
  124. }
  125. }
  126. base::TimeDelta
  127. DirectLayerTreeFrameSink::GetPreferredFrameIntervalForFrameSinkId(
  128. const viz::FrameSinkId& id,
  129. viz::mojom::CompositorFrameSinkType* type) {
  130. return frame_sink_manager_->GetPreferredFrameIntervalForFrameSinkId(id, type);
  131. }
  132. void DirectLayerTreeFrameSink::DidReceiveCompositorFrameAck(
  133. std::vector<viz::ReturnedResource> resources) {
  134. // Submitting a CompositorFrame can synchronously draw and dispatch a frame
  135. // ack. PostTask to ensure the client is notified on a new stack frame.
  136. compositor_task_runner_->PostTask(
  137. FROM_HERE,
  138. base::BindOnce(
  139. &DirectLayerTreeFrameSink::DidReceiveCompositorFrameAckInternal,
  140. weak_factory_.GetWeakPtr(), std::move(resources)));
  141. }
  142. void DirectLayerTreeFrameSink::DidReceiveCompositorFrameAckInternal(
  143. std::vector<viz::ReturnedResource> resources) {
  144. client_->ReclaimResources(std::move(resources));
  145. client_->DidReceiveCompositorFrameAck();
  146. }
  147. void DirectLayerTreeFrameSink::OnBeginFrame(
  148. const viz::BeginFrameArgs& args,
  149. const viz::FrameTimingDetailsMap& timing_details) {
  150. for (const auto& pair : timing_details)
  151. client_->DidPresentCompositorFrame(pair.first, pair.second);
  152. if (!needs_begin_frames_) {
  153. // OnBeginFrame() can be called just to deliver presentation feedback, so
  154. // report that we didn't use this BeginFrame.
  155. DidNotProduceFrame(viz::BeginFrameAck(args, false),
  156. cc::FrameSkippedReason::kNoDamage);
  157. return;
  158. }
  159. begin_frame_source_->OnBeginFrame(args);
  160. }
  161. void DirectLayerTreeFrameSink::ReclaimResources(
  162. std::vector<viz::ReturnedResource> resources) {
  163. client_->ReclaimResources(std::move(resources));
  164. }
  165. void DirectLayerTreeFrameSink::OnBeginFramePausedChanged(bool paused) {
  166. begin_frame_source_->OnSetBeginFrameSourcePaused(paused);
  167. }
  168. void DirectLayerTreeFrameSink::OnNeedsBeginFrames(bool needs_begin_frames) {
  169. needs_begin_frames_ = needs_begin_frames;
  170. support_->SetNeedsBeginFrame(needs_begin_frames);
  171. }
  172. } // namespace ui