host_frame_sink_manager.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. // Copyright 2017 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. #ifndef COMPONENTS_VIZ_HOST_HOST_FRAME_SINK_MANAGER_H_
  5. #define COMPONENTS_VIZ_HOST_HOST_FRAME_SINK_MANAGER_H_
  6. #include <memory>
  7. #include <string>
  8. #include <unordered_map>
  9. #include <vector>
  10. #include "base/compiler_specific.h"
  11. #include "base/containers/flat_map.h"
  12. #include "base/memory/raw_ptr.h"
  13. #include "base/memory/ref_counted.h"
  14. #include "base/memory/weak_ptr.h"
  15. #include "base/observer_list.h"
  16. #include "base/time/time.h"
  17. #include "components/viz/common/surfaces/frame_sink_bundle_id.h"
  18. #include "components/viz/common/surfaces/frame_sink_id.h"
  19. #include "components/viz/host/client_frame_sink_video_capturer.h"
  20. #include "components/viz/host/hit_test/hit_test_query.h"
  21. #include "components/viz/host/hit_test/hit_test_region_observer.h"
  22. #include "components/viz/host/host_frame_sink_client.h"
  23. #include "components/viz/host/viz_host_export.h"
  24. #include "mojo/public/cpp/bindings/pending_receiver.h"
  25. #include "mojo/public/cpp/bindings/pending_remote.h"
  26. #include "mojo/public/cpp/bindings/receiver.h"
  27. #include "mojo/public/cpp/bindings/remote.h"
  28. #include "services/viz/privileged/mojom/compositing/frame_sink_manager.mojom.h"
  29. #include "services/viz/public/mojom/compositing/frame_sink_bundle.mojom.h"
  30. #include "third_party/abseil-cpp/absl/types/optional.h"
  31. namespace base {
  32. class SingleThreadTaskRunner;
  33. }
  34. namespace viz {
  35. class SurfaceInfo;
  36. enum class ReportFirstSurfaceActivation { kYes, kNo };
  37. // Browser side wrapper of mojom::FrameSinkManager, to be used from the
  38. // UI thread. Manages frame sinks and is intended to replace all usage of
  39. // FrameSinkManagerImpl.
  40. class VIZ_HOST_EXPORT HostFrameSinkManager
  41. : public mojom::FrameSinkManagerClient {
  42. public:
  43. using DisplayHitTestQueryMap =
  44. base::flat_map<FrameSinkId, std::unique_ptr<HitTestQuery>>;
  45. HostFrameSinkManager();
  46. HostFrameSinkManager(const HostFrameSinkManager&) = delete;
  47. HostFrameSinkManager& operator=(const HostFrameSinkManager&) = delete;
  48. ~HostFrameSinkManager() override;
  49. const DisplayHitTestQueryMap& display_hit_test_query() const {
  50. return display_hit_test_query_;
  51. }
  52. // Sets a local FrameSinkManagerImpl instance and connects directly to it.
  53. void SetLocalManager(mojom::FrameSinkManager* frame_sink_manager);
  54. // Binds |this| as a FrameSinkManagerClient for |receiver| on |task_runner|.
  55. // On Mac |task_runner| will be the resize helper task runner. May only be
  56. // called once. If |task_runner| is null, it uses the default mojo task runner
  57. // for the thread this call is made on.
  58. void BindAndSetManager(
  59. mojo::PendingReceiver<mojom::FrameSinkManagerClient> receiver,
  60. scoped_refptr<base::SingleThreadTaskRunner> task_runner,
  61. mojo::PendingRemote<mojom::FrameSinkManager> remote);
  62. // Sets a callback to be notified when the connection to the FrameSinkManager
  63. // on |frame_sink_manager_remote_| is lost.
  64. void SetConnectionLostCallback(base::RepeatingClosure callback);
  65. // Registers |frame_sink_id| so that a client can submit CompositorFrames
  66. // using it. This must be called before creating a CompositorFrameSink or
  67. // registering FrameSinkId hierarchy.
  68. //
  69. // When the client is done submitting CompositorFrames to |frame_sink_id| then
  70. // InvalidateFrameSink() should be called.
  71. void RegisterFrameSinkId(const FrameSinkId& frame_sink_id,
  72. HostFrameSinkClient* client,
  73. ReportFirstSurfaceActivation report_activation);
  74. // Returns true if RegisterFrameSinkId() was called with |frame_sink_id| and
  75. // InvalidateFrameSinkId() has not been called.
  76. bool IsFrameSinkIdRegistered(const FrameSinkId& frame_sink_id) const;
  77. // Invalidates |frame_sink_id| when the client is done submitting
  78. // CompositorFrames. If there is a CompositorFrameSink for |frame_sink_id|
  79. // then it will be destroyed and the message pipe to the client will be
  80. // closed.
  81. //
  82. // It's expected, but not enforced, that RegisterFrameSinkId() will never be
  83. // called for |frame_sink_id| again. This is to avoid problems with re-entrant
  84. // code. If the same client wants to submit CompositorFrames later a new
  85. // FrameSinkId should be allocated.
  86. void InvalidateFrameSinkId(const FrameSinkId& frame_sink_id);
  87. // |debug_label| is used when printing out the surface hierarchy so we know
  88. // which clients are contributing which surfaces.
  89. void SetFrameSinkDebugLabel(const FrameSinkId& frame_sink_id,
  90. const std::string& debug_label);
  91. // Creates a connection from a display root to viz. Provides the same
  92. // interfaces as CreateCompositorFramesink() plus the priviledged
  93. // DisplayPrivate and (if requested) ExternalBeginFrameController interfaces.
  94. // When no longer needed, call InvalidateFrameSinkId().
  95. //
  96. // If there is already a CompositorFrameSink for |frame_sink_id| then calling
  97. // this will destroy the existing CompositorFrameSink and create a new one.
  98. void CreateRootCompositorFrameSink(
  99. mojom::RootCompositorFrameSinkParamsPtr params);
  100. // Creates a connection from a client to viz, using |request| and |client|,
  101. // that allows the client to submit CompositorFrames. When no longer needed,
  102. // call InvalidateFrameSinkId().
  103. //
  104. // If there is already a CompositorFrameSink for |frame_sink_id| then calling
  105. // this will destroy the existing CompositorFrameSink and create a new one.
  106. void CreateCompositorFrameSink(
  107. const FrameSinkId& frame_sink_id,
  108. mojo::PendingReceiver<mojom::CompositorFrameSink> receiver,
  109. mojo::PendingRemote<mojom::CompositorFrameSinkClient> client);
  110. // Creates a connection to control a set of related frame sinks through
  111. // batched IPCs on the FrameSinkBundle and FrameSinkBundleClient interfaces.
  112. // Frame sinks are added to the bundle at frame sink creation time by using
  113. // CreateBundledCompositorFrameSink with the same `bundle_id` value, rather
  114. // than using CreateCompositorFrameSink.
  115. void CreateFrameSinkBundle(
  116. const FrameSinkBundleId& bundle_id,
  117. mojo::PendingReceiver<mojom::FrameSinkBundle> receiver,
  118. mojo::PendingRemote<mojom::FrameSinkBundleClient> client);
  119. // Similar to CreateCompositorFrameSink, but the new viz-side
  120. // CompositorFrameSink object will be associated with the identified
  121. // FrameSinkBundle. This means that it will receive OnBeginFrames() and a few
  122. // other client notifications in batch with other frame sinks in the bundle
  123. // via the corresponding FrameSinkBundleClient, rather than through `client`
  124. // (though `client` is still used to send some notifications), and that its
  125. // CompositorFrames (or DidNotSubmitFrame calls) MAY be submitted in batch
  126. // through the corresponding FrameSinkBundle, rather than being sent directly
  127. // to `receiver`.
  128. void CreateBundledCompositorFrameSink(
  129. const FrameSinkId& frame_sink_id,
  130. const FrameSinkBundleId& bundle_id,
  131. mojo::PendingReceiver<mojom::CompositorFrameSink> receiver,
  132. mojo::PendingRemote<mojom::CompositorFrameSinkClient> client);
  133. // Registers FrameSink hierarchy. It's expected that the parent will embed
  134. // the child. If |parent_frame_sink_id| is registered then it will be added as
  135. // a parent of |child_frame_sink_id| and the function will return true. If
  136. // |parent_frame_sink_id| is not registered then the function will return
  137. // false. A frame sink can have multiple parents.
  138. bool RegisterFrameSinkHierarchy(const FrameSinkId& parent_frame_sink_id,
  139. const FrameSinkId& child_frame_sink_id);
  140. // Unregisters FrameSink hierarchy. Client must have registered frame sink
  141. // hierarchy before unregistering.
  142. void UnregisterFrameSinkHierarchy(const FrameSinkId& parent_frame_sink_id,
  143. const FrameSinkId& child_frame_sink_id);
  144. // Asks viz to send updates regarding video activity to |observer|.
  145. void AddVideoDetectorObserver(
  146. mojo::PendingRemote<mojom::VideoDetectorObserver> observer);
  147. // Creates a FrameSinkVideoCapturer instance in viz.
  148. void CreateVideoCapturer(
  149. mojo::PendingReceiver<mojom::FrameSinkVideoCapturer> receiver);
  150. // Creates a FrameSinkVideoCapturer instance in viz and returns a
  151. // ClientFrameSinkVideoCapturer that's connected to it. Clients should prefer
  152. // this version because ClientFrameSinkVideoCapturer is resilient to viz
  153. // crashes.
  154. std::unique_ptr<ClientFrameSinkVideoCapturer> CreateVideoCapturer();
  155. // Marks the given SurfaceIds for destruction.
  156. void EvictSurfaces(const std::vector<SurfaceId>& surface_ids);
  157. // Takes snapshot of a |surface_id| or a newer surface with the same
  158. // FrameSinkId. The FrameSinkId is used to identify which frame we're
  159. // interested in. The snapshot will only be taken if the LocalSurfaceId is at
  160. // least the given LocalSurfaceId (|surface_id.local_frame_id()|). If the
  161. // LocalSurfaceId is lower than the given id, then the request is queued up to
  162. // be executed later.
  163. void RequestCopyOfOutput(const SurfaceId& surface_id,
  164. std::unique_ptr<CopyOutputRequest> request);
  165. void Throttle(const std::vector<FrameSinkId>& ids, base::TimeDelta interval);
  166. void StartThrottlingAllFrameSinks(base::TimeDelta interval);
  167. void StopThrottlingAllFrameSinks();
  168. // Add/Remove an observer to receive notifications of when the host receives
  169. // new hit test data.
  170. void AddHitTestRegionObserver(HitTestRegionObserver* observer);
  171. void RemoveHitTestRegionObserver(HitTestRegionObserver* observer);
  172. void SetHitTestAsyncQueriedDebugRegions(
  173. const FrameSinkId& root_frame_sink_id,
  174. const std::vector<FrameSinkId>& hit_test_async_queried_debug_queue);
  175. // Preserves the back buffer associated with the |root_sink_id|, even after
  176. // the associated Display has been torn down, and returns an id for this cache
  177. // entry.
  178. uint32_t CacheBackBufferForRootSink(const FrameSinkId& root_sink_id);
  179. void EvictCachedBackBuffer(uint32_t cache_id);
  180. void CreateHitTestQueryForSynchronousCompositor(
  181. const FrameSinkId& frame_sink_id);
  182. void EraseHitTestQueryForSynchronousCompositor(
  183. const FrameSinkId& frame_sink_id);
  184. void UpdateDebugRendererSettings(const DebugRendererSettings& debug_settings);
  185. const DebugRendererSettings& debug_renderer_settings() const {
  186. return debug_renderer_settings_;
  187. }
  188. private:
  189. friend class HostFrameSinkManagerTest;
  190. friend class HostFrameSinkManagerTestApi;
  191. struct FrameSinkData {
  192. FrameSinkData();
  193. FrameSinkData(const FrameSinkData&) = delete;
  194. FrameSinkData& operator=(const FrameSinkData&) = delete;
  195. FrameSinkData(FrameSinkData&& other);
  196. FrameSinkData& operator=(FrameSinkData&& other);
  197. ~FrameSinkData();
  198. bool IsFrameSinkRegistered() const { return client != nullptr; }
  199. // Returns true if there is nothing in FrameSinkData and it can be deleted.
  200. bool IsEmpty() const {
  201. return !IsFrameSinkRegistered() && !has_created_compositor_frame_sink &&
  202. children.empty();
  203. }
  204. // The client to be notified of changes to this FrameSink.
  205. raw_ptr<HostFrameSinkClient> client = nullptr;
  206. // Indicates whether or not this client cares to receive
  207. // FirstSurfaceActivation notifications.
  208. ReportFirstSurfaceActivation report_activation =
  209. ReportFirstSurfaceActivation::kYes;
  210. // The name of the HostFrameSinkClient used for debug purposes.
  211. std::string debug_label;
  212. // If the frame sink is a root that corresponds to a Display.
  213. bool is_root = false;
  214. // If we should wait on synchronous destruction.
  215. bool wait_on_destruction = false;
  216. // If a mojom::CompositorFrameSink was created for this FrameSinkId. This
  217. // will always be false if not using Mojo.
  218. bool has_created_compositor_frame_sink = false;
  219. // Track frame sink hierarchy.
  220. std::vector<FrameSinkId> children;
  221. };
  222. void CreateFrameSink(
  223. const FrameSinkId& frame_sink_id,
  224. absl::optional<FrameSinkBundleId> bundle_id,
  225. mojo::PendingReceiver<mojom::CompositorFrameSink> receiver,
  226. mojo::PendingRemote<mojom::CompositorFrameSinkClient> client);
  227. // Handles connection loss to |frame_sink_manager_remote_|. This should only
  228. // happen when the GPU process crashes.
  229. void OnConnectionLost();
  230. // Registers FrameSinkId and FrameSink hierarchy again after connection loss.
  231. void RegisterAfterConnectionLoss();
  232. // mojom::FrameSinkManagerClient:
  233. void OnFrameTokenChanged(const FrameSinkId& frame_sink_id,
  234. uint32_t frame_token,
  235. base::TimeTicks activation_time) override;
  236. void OnFirstSurfaceActivation(const SurfaceInfo& surface_info) override;
  237. void OnAggregatedHitTestRegionListUpdated(
  238. const FrameSinkId& frame_sink_id,
  239. const std::vector<AggregatedHitTestRegion>& hit_test_data) override;
  240. const bool enable_sync_window_destruction_;
  241. // Connections to/from FrameSinkManagerImpl.
  242. mojo::Remote<mojom::FrameSinkManager> frame_sink_manager_remote_;
  243. // This will point to |frame_sink_manager_remote_| if using mojo or it may
  244. // point directly at FrameSinkManagerImpl in tests. Use this to make function
  245. // calls.
  246. raw_ptr<mojom::FrameSinkManager> frame_sink_manager_ = nullptr;
  247. mojo::Receiver<mojom::FrameSinkManagerClient> receiver_{this};
  248. // Per CompositorFrameSink data.
  249. std::unordered_map<FrameSinkId, FrameSinkData, FrameSinkIdHash>
  250. frame_sink_data_map_;
  251. // If |frame_sink_manager_remote_| connection was lost.
  252. bool connection_was_lost_ = false;
  253. base::RepeatingClosure connection_lost_callback_;
  254. DisplayHitTestQueryMap display_hit_test_query_;
  255. // TODO(jonross): Separate out all hit testing work into its own separate
  256. // class.
  257. base::ObserverList<HitTestRegionObserver>::Unchecked observers_;
  258. uint32_t next_cache_back_buffer_id_ = 1;
  259. uint32_t min_valid_cache_back_buffer_id_ = 1;
  260. // This is kept in sync with implementation.
  261. DebugRendererSettings debug_renderer_settings_;
  262. base::WeakPtrFactory<HostFrameSinkManager> weak_ptr_factory_{this};
  263. };
  264. } // namespace viz
  265. #endif // COMPONENTS_VIZ_HOST_HOST_FRAME_SINK_MANAGER_H_