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 
5 #ifndef COMPONENTS_VIZ_SERVICE_FRAME_SINKS_FRAME_SINK_MANAGER_IMPL_H_
6 #define COMPONENTS_VIZ_SERVICE_FRAME_SINKS_FRAME_SINK_MANAGER_IMPL_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 #include "base/callback_helpers.h"
15 #include "base/containers/flat_map.h"
16 #include "base/containers/flat_set.h"
17 #include "base/containers/unique_ptr_adapters.h"
18 #include "base/logging.h"
19 #include "base/macros.h"
20 #include "base/optional.h"
21 #include "base/single_thread_task_runner.h"
22 #include "base/strings/string_piece.h"
23 #include "base/threading/thread_checker.h"
24 #include "components/viz/common/constants.h"
25 #include "components/viz/common/surfaces/frame_sink_id.h"
26 #include "components/viz/service/frame_sinks/compositor_frame_sink_impl.h"
27 #include "components/viz/service/frame_sinks/frame_sink_observer.h"
28 #include "components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h"
29 #include "components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_manager.h"
30 #include "components/viz/service/frame_sinks/video_detector.h"
31 #include "components/viz/service/hit_test/hit_test_aggregator_delegate.h"
32 #include "components/viz/service/hit_test/hit_test_manager.h"
33 #include "components/viz/service/surfaces/surface_manager.h"
34 #include "components/viz/service/surfaces/surface_manager_delegate.h"
35 #include "components/viz/service/surfaces/surface_observer.h"
36 #include "components/viz/service/viz_service_export.h"
37 #include "gpu/ipc/common/surface_handle.h"
38 #include "mojo/public/cpp/bindings/pending_receiver.h"
39 #include "mojo/public/cpp/bindings/pending_remote.h"
40 #include "mojo/public/cpp/bindings/receiver.h"
41 #include "mojo/public/cpp/bindings/remote.h"
42 #include "services/viz/privileged/mojom/compositing/frame_sink_manager.mojom.h"
43 #include "services/viz/privileged/mojom/compositing/frame_sink_video_capture.mojom.h"
44 #include "services/viz/public/mojom/compositing/video_detector_observer.mojom.h"
45 
46 namespace viz {
47 
48 class CapturableFrameSink;
49 class CompositorFrameSinkSupport;
50 class OutputSurfaceProvider;
51 class SharedBitmapManager;
52 
53 // FrameSinkManagerImpl manages BeginFrame hierarchy. This is the implementation
54 // detail for FrameSinkManagerImpl.
55 class VIZ_SERVICE_EXPORT FrameSinkManagerImpl
56     : public SurfaceObserver,
57       public FrameSinkVideoCapturerManager,
58       public mojom::FrameSinkManager,
59       public HitTestAggregatorDelegate,
60       public SurfaceManagerDelegate {
61  public:
62   struct VIZ_SERVICE_EXPORT InitParams {
63     InitParams();
64     InitParams(SharedBitmapManager* shared_bitmap_manager,
65                OutputSurfaceProvider* output_surface_provider);
66     InitParams(InitParams&& other);
67     ~InitParams();
68     InitParams& operator=(InitParams&& other);
69 
70     SharedBitmapManager* shared_bitmap_manager = nullptr;
71     base::Optional<uint32_t> activation_deadline_in_frames =
72         kDefaultActivationDeadlineInFrames;
73     OutputSurfaceProvider* output_surface_provider = nullptr;
74     uint32_t restart_id = BeginFrameSource::kNotRestartableId;
75     bool run_all_compositor_stages_before_draw = false;
76     bool log_capture_pipeline_in_webrtc = false;
77   };
78   explicit FrameSinkManagerImpl(const InitParams& params);
79   // TODO(kylechar): Cleanup tests and remove this constructor.
80   FrameSinkManagerImpl(
81       SharedBitmapManager* shared_bitmap_manager,
82       OutputSurfaceProvider* output_surface_provider = nullptr);
83   ~FrameSinkManagerImpl() override;
84 
85   // Performs cleanup needed to force shutdown from the GPU process. Stops all
86   // incoming IPCs and destroys all [Root]CompositorFrameSinkImpls.
87   void ForceShutdown();
88 
89   // Binds |this| as a FrameSinkManagerImpl for |receiver| on |task_runner|. On
90   // Mac |task_runner| will be the resize helper task runner. May only be called
91   // once.
92   void BindAndSetClient(
93       mojo::PendingReceiver<mojom::FrameSinkManager> receiver,
94       scoped_refptr<base::SingleThreadTaskRunner> task_runner,
95       mojo::PendingRemote<mojom::FrameSinkManagerClient> client);
96 
97   // Sets up a direction connection to |client| without using Mojo.
98   void SetLocalClient(
99       mojom::FrameSinkManagerClient* client,
100       scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner = nullptr);
101 
102   // mojom::FrameSinkManager implementation:
103   void RegisterFrameSinkId(const FrameSinkId& frame_sink_id,
104                            bool report_activation) override;
105   void InvalidateFrameSinkId(const FrameSinkId& frame_sink_id) override;
106   void SetFrameSinkDebugLabel(const FrameSinkId& frame_sink_id,
107                               const std::string& debug_label) override;
108   void CreateRootCompositorFrameSink(
109       mojom::RootCompositorFrameSinkParamsPtr params) override;
110   void CreateCompositorFrameSink(
111       const FrameSinkId& frame_sink_id,
112       mojo::PendingReceiver<mojom::CompositorFrameSink> receiver,
113       mojo::PendingRemote<mojom::CompositorFrameSinkClient> client) override;
114   void DestroyCompositorFrameSink(
115       const FrameSinkId& frame_sink_id,
116       DestroyCompositorFrameSinkCallback callback) override;
117   void RegisterFrameSinkHierarchy(
118       const FrameSinkId& parent_frame_sink_id,
119       const FrameSinkId& child_frame_sink_id) override;
120   void UnregisterFrameSinkHierarchy(
121       const FrameSinkId& parent_frame_sink_id,
122       const FrameSinkId& child_frame_sink_id) override;
123   void AddVideoDetectorObserver(
124       mojo::PendingRemote<mojom::VideoDetectorObserver> observer) override;
125   void CreateVideoCapturer(
126       mojo::PendingReceiver<mojom::FrameSinkVideoCapturer> receiver) override;
127   void EvictSurfaces(const std::vector<SurfaceId>& surface_ids) override;
128   void RequestCopyOfOutput(const SurfaceId& surface_id,
129                            std::unique_ptr<CopyOutputRequest> request) override;
130   void SetHitTestAsyncQueriedDebugRegions(
131       const FrameSinkId& root_frame_sink_id,
132       const std::vector<FrameSinkId>& hit_test_async_queried_debug_queue)
133       override;
134   void CacheBackBuffer(uint32_t cache_id,
135                        const FrameSinkId& root_frame_sink_id) override;
136   void EvictBackBuffer(uint32_t cache_id,
137                        EvictBackBufferCallback callback) override;
138 
139   // SurfaceObserver implementation.
140   void OnFirstSurfaceActivation(const SurfaceInfo& surface_info) override;
141 
142   // HitTestAggregatorDelegate implementation:
143   void OnAggregatedHitTestRegionListUpdated(
144       const FrameSinkId& frame_sink_id,
145       const std::vector<AggregatedHitTestRegion>& hit_test_data) override;
146 
147   // SurfaceManagerDelegate implementation:
148   base::StringPiece GetFrameSinkDebugLabel(
149       const FrameSinkId& frame_sink_id) const override;
150   void AggregatedFrameSinksChanged() override;
151 
152   // CompositorFrameSinkSupport, hierarchy, and BeginFrameSource can be
153   // registered and unregistered in any order with respect to each other.
154   //
155   // This happens in practice, e.g. the relationship to between ui::Compositor /
156   // DelegatedFrameHost is known before ui::Compositor has a surface/client).
157   // However, DelegatedFrameHost can register itself as a client before its
158   // relationship with the ui::Compositor is known.
159 
160   // Registers a CompositorFrameSinkSupport for |frame_sink_id|. |frame_sink_id|
161   // must be unregistered when |support| is destroyed.
162   void RegisterCompositorFrameSinkSupport(const FrameSinkId& frame_sink_id,
163                                           CompositorFrameSinkSupport* support);
164   void UnregisterCompositorFrameSinkSupport(const FrameSinkId& frame_sink_id);
165 
166   // Associates a |source| with a particular framesink.  That framesink and
167   // any children of that framesink with valid clients can potentially use
168   // that |source|.
169   void RegisterBeginFrameSource(BeginFrameSource* source,
170                                 const FrameSinkId& frame_sink_id);
171   void UnregisterBeginFrameSource(BeginFrameSource* source);
172 
surface_manager()173   SurfaceManager* surface_manager() { return &surface_manager_; }
hit_test_manager()174   const HitTestManager* hit_test_manager() { return &hit_test_manager_; }
shared_bitmap_manager()175   SharedBitmapManager* shared_bitmap_manager() {
176     return shared_bitmap_manager_;
177   }
178 
179   void SubmitHitTestRegionList(
180       const SurfaceId& surface_id,
181       uint64_t frame_index,
182       base::Optional<HitTestRegionList> hit_test_region_list);
183 
184   // Instantiates |video_detector_| for tests where we simulate the passage of
185   // time.
186   VideoDetector* CreateVideoDetectorForTesting(
187       const base::TickClock* tick_clock,
188       scoped_refptr<base::SequencedTaskRunner> task_runner);
189 
190   void OnFrameTokenChangedDirect(const FrameSinkId& frame_sink_id,
191                                  uint32_t frame_token);
192 
193   // Called when |frame_token| is changed on a submitted CompositorFrame.
194   void OnFrameTokenChanged(const FrameSinkId& frame_sink_id,
195                            uint32_t frame_token);
196 
197   void DidBeginFrame(const FrameSinkId& frame_sink_id,
198                      const BeginFrameArgs& args);
199   void DidFinishFrame(const FrameSinkId& frame_sink_id,
200                       const BeginFrameArgs& args);
201 
202   void AddObserver(FrameSinkObserver* obs);
203   void RemoveObserver(FrameSinkObserver* obs);
204 
205   // Returns ids of all FrameSinks that were registered.
206   std::vector<FrameSinkId> GetRegisteredFrameSinkIds() const;
207 
208   // Returns children of a FrameSink that has |parent_frame_sink_id|.
209   // Returns an empty set if a parent doesn't have any children.
210   base::flat_set<FrameSinkId> GetChildrenByParent(
211       const FrameSinkId& parent_frame_sink_id) const;
212   const CompositorFrameSinkSupport* GetFrameSinkForId(
213       const FrameSinkId& frame_sink_id) const;
214 
215   void SetPreferredFrameIntervalForFrameSinkId(const FrameSinkId& id,
216                                                base::TimeDelta interval);
217   base::TimeDelta GetPreferredFrameIntervalForFrameSinkId(
218       const FrameSinkId& id) const;
219 
220   // This cancels pending output requests owned by the frame sinks associated
221   // with the specified BeginFrameSource.
222   // The requets callback will be fired as part of request destruction.
223   // This may be used in case we know a frame can't be produced any time soon,
224   // so there's no point for caller to wait for the copy of output.
225   void DiscardPendingCopyOfOutputRequests(const BeginFrameSource* source);
226 
227  private:
228   friend class FrameSinkManagerTest;
229 
230   // Metadata for a CompositorFrameSink.
231   struct FrameSinkData {
232     explicit FrameSinkData(bool report_activation);
233     FrameSinkData(FrameSinkData&& other);
234     ~FrameSinkData();
235     FrameSinkData& operator=(FrameSinkData&& other);
236 
237     // A label to identify frame sink.
238     std::string debug_label;
239 
240     // Indicates whether the client wishes to receive FirstSurfaceActivation
241     // notification.
242     bool report_activation;
243 
244     base::TimeDelta preferred_frame_interval = BeginFrameArgs::MinInterval();
245 
246    private:
247     DISALLOW_COPY_AND_ASSIGN(FrameSinkData);
248   };
249 
250   // BeginFrameSource routing information for a FrameSinkId.
251   struct FrameSinkSourceMapping {
252     FrameSinkSourceMapping();
253     FrameSinkSourceMapping(FrameSinkSourceMapping&& other);
254     ~FrameSinkSourceMapping();
255     FrameSinkSourceMapping& operator=(FrameSinkSourceMapping&& other);
256 
257     // The currently assigned begin frame source for this client.
258     BeginFrameSource* source = nullptr;
259     // This represents a dag of parent -> children mapping.
260     base::flat_set<FrameSinkId> children;
261 
262    private:
263     DISALLOW_COPY_AND_ASSIGN(FrameSinkSourceMapping);
264   };
265 
266   void RecursivelyAttachBeginFrameSource(const FrameSinkId& frame_sink_id,
267                                          BeginFrameSource* source);
268   void RecursivelyDetachBeginFrameSource(const FrameSinkId& frame_sink_id,
269                                          BeginFrameSource* source);
270 
271   // FrameSinkVideoCapturerManager implementation:
272   CapturableFrameSink* FindCapturableFrameSink(
273       const FrameSinkId& frame_sink_id) override;
274   void OnCapturerConnectionLost(FrameSinkVideoCapturerImpl* capturer) override;
275 
276   // Returns true if |child framesink| is or has |search_frame_sink_id| as a
277   // child.
278   bool ChildContains(const FrameSinkId& child_frame_sink_id,
279                      const FrameSinkId& search_frame_sink_id) const;
280 
281   // SharedBitmapManager for the viz display service for receiving software
282   // resources in CompositorFrameSinks.
283   SharedBitmapManager* const shared_bitmap_manager_;
284 
285   // Provides an output surface for CreateRootCompositorFrameSink().
286   OutputSurfaceProvider* const output_surface_provider_;
287 
288   SurfaceManager surface_manager_;
289 
290   // Must be created after and destroyed before |surface_manager_|.
291   HitTestManager hit_test_manager_;
292 
293   // Restart id to generate unique begin frames across process restarts.  Used
294   // for creating a BeginFrameSource for RootCompositorFrameSink.
295   const uint32_t restart_id_;
296 
297   // Whether display scheduler should wait for all pipeline stages before draw.
298   const bool run_all_compositor_stages_before_draw_;
299 
300   // Whether capture pipeline should emit log messages to webrtc log.
301   const bool log_capture_pipeline_in_webrtc_;
302 
303   // Contains registered frame sink ids, debug labels and synchronization
304   // labels. Map entries will be created when frame sink is registered and
305   // destroyed when frame sink is invalidated.
306   base::flat_map<FrameSinkId, FrameSinkData> frame_sink_data_;
307 
308   // Set of BeginFrameSource along with associated FrameSinkIds. Any child
309   // that is implicitly using this frame sink must be reachable by the
310   // parent in the dag.
311   base::flat_map<BeginFrameSource*, FrameSinkId> registered_sources_;
312 
313   // Contains FrameSinkId hierarchy and BeginFrameSource mapping.
314   base::flat_map<FrameSinkId, FrameSinkSourceMapping> frame_sink_source_map_;
315 
316   // CompositorFrameSinkSupports get added to this map on creation and removed
317   // on destruction.
318   base::flat_map<FrameSinkId, CompositorFrameSinkSupport*> support_map_;
319 
320   // [Root]CompositorFrameSinkImpls are owned in these maps.
321   base::flat_map<FrameSinkId, std::unique_ptr<RootCompositorFrameSinkImpl>>
322       root_sink_map_;
323   base::flat_map<FrameSinkId, std::unique_ptr<CompositorFrameSinkImpl>>
324       sink_map_;
325 
326   base::flat_set<std::unique_ptr<FrameSinkVideoCapturerImpl>,
327                  base::UniquePtrComparator>
328       video_capturers_;
329 
330   base::flat_map<uint32_t, base::ScopedClosureRunner> cached_back_buffers_;
331 
332   THREAD_CHECKER(thread_checker_);
333 
334   // |video_detector_| is instantiated lazily in order to avoid overhead on
335   // platforms that don't need video detection.
336   std::unique_ptr<VideoDetector> video_detector_;
337 
338   // There are three states this can be in:
339   //  1. Mojo client: |client_| will point to |client_remote_|, the Mojo client,
340   //     and |ui_task_runner_| will not be used. Calls to OnFrameTokenChanged()
341   //     will go through Mojo. This is the normal state.
342   //  2. Local (directly connected) client, *with* task runner: |client_| will
343   //     point to the client, |client_remote_| will not be bound to any remote
344   //     client, and calls to OnFrameTokenChanged() will be PostTasked using
345   //     |ui_task_runner_|. Used mostly for layout tests.
346   //  3. Local (directly connected) client, *without* task runner: |client_|
347   //     will point to the client, |client_remote_| will not be bound to any
348   //     remote client and |ui_task_runner_| will be nullptr, and calls to
349   //     OnFrameTokenChanged() will be directly called (without PostTask) on
350   //     |client_|. Used for some unit tests.
351   mojom::FrameSinkManagerClient* client_ = nullptr;
352   scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_ = nullptr;
353   mojo::Remote<mojom::FrameSinkManagerClient> client_remote_;
354   mojo::Receiver<mojom::FrameSinkManager> receiver_{this};
355 
356   base::ObserverList<FrameSinkObserver>::Unchecked observer_list_;
357 
358   DISALLOW_COPY_AND_ASSIGN(FrameSinkManagerImpl);
359 };
360 
361 }  // namespace viz
362 
363 #endif  // COMPONENTS_VIZ_SERVICE_FRAME_SINKS_FRAME_SINK_MANAGER_IMPL_H_
364