File: frame_sink_manager_impl.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (624 lines) | stat: -rw-r--r-- 27,701 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_VIZ_SERVICE_FRAME_SINKS_FRAME_SINK_MANAGER_IMPL_H_
#define COMPONENTS_VIZ_SERVICE_FRAME_SINKS_FRAME_SINK_MANAGER_IMPL_H_

#include <stdint.h>

#include <list>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <vector>

#include "base/check.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "base/sequence_checker.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "components/input/render_input_router.mojom.h"
#include "components/viz/common/constants.h"
#include "components/viz/common/hit_test/hit_test_data_provider.h"
#include "components/viz/common/surfaces/frame_sink_bundle_id.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/service/display/overdraw_tracker.h"
#include "components/viz/service/frame_sinks/compositor_frame_sink_impl.h"
#include "components/viz/service/frame_sinks/frame_counter.h"
#include "components/viz/service/frame_sinks/frame_sink_observer.h"
#include "components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h"
#include "components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_manager.h"
#include "components/viz/service/frame_sinks/video_detector.h"
#include "components/viz/service/gl/gpu_service_impl.h"
#include "components/viz/service/hit_test/hit_test_aggregator_delegate.h"
#include "components/viz/service/hit_test/hit_test_manager.h"
#include "components/viz/service/surfaces/surface_manager.h"
#include "components/viz/service/surfaces/surface_manager_delegate.h"
#include "components/viz/service/surfaces/surface_observer.h"
#include "components/viz/service/viz_service_export.h"
#include "gpu/ipc/common/surface_handle.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/viz/privileged/mojom/compositing/frame_sink_manager.mojom.h"
#include "services/viz/privileged/mojom/compositing/frame_sink_manager_test_api.mojom.h"
#include "services/viz/privileged/mojom/compositing/frame_sink_video_capture.mojom.h"
#include "services/viz/privileged/mojom/compositing/frame_sinks_metrics_recorder.mojom.h"
#include "services/viz/public/mojom/compositing/video_detector_observer.mojom.h"

namespace viz {

class CapturableFrameSink;
class CompositorFrameSinkSupport;
class FrameSinkBundleImpl;
class GmbVideoFramePoolContextProvider;
class HintSessionFactory;
class InputManager;
class OutputSurfaceProvider;
class SharedImageInterfaceProvider;
struct VideoCaptureTarget;

// FrameSinkManagerImpl manages BeginFrame hierarchy. This is the implementation
// detail for FrameSinkManagerImpl.
class VIZ_SERVICE_EXPORT FrameSinkManagerImpl
    : public SurfaceObserver,
      public FrameSinkVideoCapturerManager,
      public mojom::FrameSinkManager,
      public mojom::FrameSinksMetricsRecorder,
      public mojom::FrameSinkManagerTestApi,
      public HitTestAggregatorDelegate,
      public SurfaceManagerDelegate,
      public HitTestDataProvider {
 public:
  struct VIZ_SERVICE_EXPORT InitParams {
    explicit InitParams(
        OutputSurfaceProvider* output_surface_provider = nullptr,
        GmbVideoFramePoolContextProvider* gmb_context_provider = nullptr);
    InitParams(InitParams&& other);
    ~InitParams();
    InitParams& operator=(InitParams&& other);

    std::optional<uint32_t> activation_deadline_in_frames =
        kDefaultActivationDeadlineInFrames;
    raw_ptr<OutputSurfaceProvider> output_surface_provider = nullptr;
    raw_ptr<GpuServiceImpl> gpu_service = nullptr;
    raw_ptr<GmbVideoFramePoolContextProvider> gmb_context_provider = nullptr;
    uint32_t restart_id = BeginFrameSource::kNotRestartableId;
    bool run_all_compositor_stages_before_draw = false;
    bool log_capture_pipeline_in_webrtc = false;
    DebugRendererSettings debug_renderer_settings;
    base::ProcessId host_process_id = base::kNullProcessId;
    raw_ptr<HintSessionFactory> hint_session_factory = nullptr;
    size_t max_uncommitted_frames = 0;
  };
  explicit FrameSinkManagerImpl(const InitParams& params);

  FrameSinkManagerImpl(const FrameSinkManagerImpl&) = delete;
  FrameSinkManagerImpl& operator=(const FrameSinkManagerImpl&) = delete;

  ~FrameSinkManagerImpl() override;

  CompositorFrameSinkImpl* GetFrameSinkImpl(const FrameSinkId& id);
  FrameSinkBundleImpl* GetFrameSinkBundle(const FrameSinkBundleId& id);

  // Binds |this| as a FrameSinkManagerImpl for |receiver| on |task_runner|. On
  // Mac |task_runner| will be the resize helper task runner. May only be called
  // once.
  void BindAndSetClient(
      mojo::PendingReceiver<mojom::FrameSinkManager> receiver,
      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
      mojo::PendingRemote<mojom::FrameSinkManagerClient> client,
      SharedImageInterfaceProvider* shared_image_interface_provider);

  void SetSharedImageInterfaceProviderForTest(
      SharedImageInterfaceProvider* provider) {
    shared_image_interface_provider_ = provider;
  }

  void SetInputManagerForTesting(std::unique_ptr<InputManager> input_manager);

  // Sets up a direction connection to |client| without using Mojo.
  void SetLocalClient(
      mojom::FrameSinkManagerClient* client,
      scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner = nullptr);

  // mojom::FrameSinkManager implementation:
  void RegisterFrameSinkId(const FrameSinkId& frame_sink_id,
                           bool report_activation) override;
  void InvalidateFrameSinkId(const FrameSinkId& frame_sink_id) override;
  void SetFrameSinkDebugLabel(const FrameSinkId& frame_sink_id,
                              const std::string& debug_label) override;
  void CreateRootCompositorFrameSink(
      mojom::RootCompositorFrameSinkParamsPtr params) override;
  void CreateFrameSinkBundle(
      const FrameSinkBundleId& bundle_id,
      mojo::PendingReceiver<mojom::FrameSinkBundle> receiver,
      mojo::PendingRemote<mojom::FrameSinkBundleClient> client) override;
  void CreateCompositorFrameSink(
      const FrameSinkId& frame_sink_id,
      const std::optional<FrameSinkBundleId>& bundle_id,
      mojo::PendingReceiver<mojom::CompositorFrameSink> receiver,
      mojo::PendingRemote<mojom::CompositorFrameSinkClient> client,
      input::mojom::RenderInputRouterConfigPtr render_input_router_config)
      override;
  void DestroyCompositorFrameSink(
      const FrameSinkId& frame_sink_id,
      DestroyCompositorFrameSinkCallback callback) override;
  void RegisterFrameSinkHierarchy(
      const FrameSinkId& parent_frame_sink_id,
      const FrameSinkId& child_frame_sink_id) override;
  void UnregisterFrameSinkHierarchy(
      const FrameSinkId& parent_frame_sink_id,
      const FrameSinkId& child_frame_sink_id) override;
  void AddVideoDetectorObserver(
      mojo::PendingRemote<mojom::VideoDetectorObserver> observer) override;
  void CreateVideoCapturer(
      mojo::PendingReceiver<mojom::FrameSinkVideoCapturer> receiver) override;
  void EvictSurfaces(const std::vector<SurfaceId>& surface_ids) override;
  void RequestCopyOfOutput(const SurfaceId& surface_id,
                           std::unique_ptr<CopyOutputRequest> request,
                           bool capture_exact_surface_id) override;
#if BUILDFLAG(IS_ANDROID)
  void CacheBackBuffer(uint32_t cache_id,
                       const FrameSinkId& root_frame_sink_id) override;
  void EvictBackBuffer(uint32_t cache_id,
                       EvictBackBufferCallback callback) override;
#endif
  void UpdateDebugRendererSettings(
      const DebugRendererSettings& debug_settings) override;
  void Throttle(const std::vector<FrameSinkId>& ids,
                base::TimeDelta interval) override;
  void StartThrottlingAllFrameSinks(base::TimeDelta interval) override;
  void StopThrottlingAllFrameSinks() override;
  void ClearUnclaimedViewTransitionResources(
      const blink::ViewTransitionToken& transition_token) override;
  void CreateMetricsRecorderForTest(
      mojo::PendingReceiver<mojom::FrameSinksMetricsRecorder> receiver)
      override;
  void EnableFrameSinkManagerTestApi(
      mojo::PendingReceiver<mojom::FrameSinkManagerTestApi> receiver) override;
  void SetupRendererInputRouterDelegateRegistry(
      mojo::PendingReceiver<mojom::RendererInputRouterDelegateRegistry>
          receiver) override;
  void NotifyRendererBlockStateChanged(
      bool blocked,
      const std::vector<FrameSinkId>& render_input_routers) override;
  void RequestInputBack() override;

  // mojom::FrameSinksMetricsTracker implementation:
  void StartFrameCounting(base::TimeTicks start_time,
                          base::TimeDelta bucket_size) override;
  void StopFrameCounting(StopFrameCountingCallback callback) override;
  void StartOverdrawTracking(const FrameSinkId& root_frame_sink_id,
                             base::TimeDelta bucket_size) override;
  void StopOverdrawTracking(const FrameSinkId& root_frame_sink_id,
                            StopOverdrawTrackingCallback callback) override;

  // mojom::FrameSinkManagerTestApi implementation:
  void HasUnclaimedViewTransitionResources(
      HasUnclaimedViewTransitionResourcesCallback callback) override;
  void SetSameDocNavigationScreenshotSize(
      const gfx::Size& result_size,
      SetSameDocNavigationScreenshotSizeCallback callback) override;
  void GetForceEnableZoomState(
      const FrameSinkId& frame_sink_id,
      GetForceEnableZoomStateCallback callback) override;
  void WaitForSurfaceAnimationManager(
      const FrameSinkId& frame_sink_id,
      WaitForSurfaceAnimationManagerCallback callback) override;

  void DestroyFrameSinkBundle(const FrameSinkBundleId& id);

  // SurfaceObserver implementation.
  void OnFirstSurfaceActivation(const SurfaceInfo& surface_info) override;

  void UpdateHitTestRegionData(
      const FrameSinkId& frame_sink_id,
      const std::vector<AggregatedHitTestRegion>& hit_test_data);

  // HitTestAggregatorDelegate implementation:
  void OnAggregatedHitTestRegionListUpdated(
      const FrameSinkId& frame_sink_id,
      const std::vector<AggregatedHitTestRegion>& hit_test_data) override;

  // SurfaceManagerDelegate implementation:
  std::string_view GetFrameSinkDebugLabel(
      const FrameSinkId& frame_sink_id) const override;
  void AggregatedFrameSinksChanged() override;

  // HitTestDataProvider implementation.
  // This is required to allow RenderWidgetHostInputEventRouter to find target
  // view synchronously with InputVizard.
  void AddHitTestRegionObserver(HitTestRegionObserver* observer) override;
  void RemoveHitTestRegionObserver(HitTestRegionObserver* observer) override;
  const DisplayHitTestQueryMap& GetDisplayHitTestQuery() const override;

  // CompositorFrameSinkSupport, hierarchy, and BeginFrameSource can be
  // registered and unregistered in any order with respect to each other.
  //
  // This happens in practice, e.g. the relationship to between ui::Compositor /
  // DelegatedFrameHost is known before ui::Compositor has a surface/client).
  // However, DelegatedFrameHost can register itself as a client before its
  // relationship with the ui::Compositor is known.

  // Registers a CompositorFrameSinkSupport for |frame_sink_id|. |frame_sink_id|
  // must be unregistered when |support| is destroyed.
  void RegisterCompositorFrameSinkSupport(const FrameSinkId& frame_sink_id,
                                          CompositorFrameSinkSupport* support);
  void UnregisterCompositorFrameSinkSupport(const FrameSinkId& frame_sink_id);

  // Associates a |source| with a particular framesink.  That framesink and
  // any children of that framesink with valid clients can potentially use
  // that |source|.
  void RegisterBeginFrameSource(BeginFrameSource* source,
                                const FrameSinkId& frame_sink_id);
  void UnregisterBeginFrameSource(BeginFrameSource* source);

  SurfaceManager* surface_manager() { return &surface_manager_; }
  const HitTestManager* hit_test_manager() { return &hit_test_manager_; }

  virtual InputManager* GetInputManager();  // virtual for testing.

  void SubmitHitTestRegionList(
      const SurfaceId& surface_id,
      uint64_t frame_index,
      std::optional<HitTestRegionList> hit_test_region_list);

  // Instantiates |video_detector_| for tests where we simulate the passage of
  // time.
  VideoDetector* CreateVideoDetectorForTesting(
      const base::TickClock* tick_clock,
      scoped_refptr<base::SequencedTaskRunner> task_runner);

  void OnFrameTokenChangedDirect(const FrameSinkId& frame_sink_id,
                                 uint32_t frame_token,
                                 base::TimeTicks activation_time);

  // Called when |frame_token| is changed on a submitted CompositorFrame.
  void OnFrameTokenChanged(const FrameSinkId& frame_sink_id,
                           uint32_t frame_token);

  void DidBeginFrame(const FrameSinkId& frame_sink_id,
                     const BeginFrameArgs& args);
  void DidFinishFrame(const FrameSinkId& frame_sink_id,
                      const BeginFrameArgs& args);

  void OnFrameSinkDeviceScaleFactorChanged(const FrameSinkId& frame_sink_id,
                                           float device_scale_factor);

  void OnFrameSinkMobileOptimizedChanged(const FrameSinkId& frame_sink_id,
                                         bool is_mobile_optimized);

  void AddObserver(FrameSinkObserver* obs);
  void RemoveObserver(FrameSinkObserver* obs);

  // Returns ids of all FrameSinks that were registered.
  std::vector<FrameSinkId> GetRegisteredFrameSinkIds() const;

  // Returns oldest(first) parent's FrameSinkId attached to
  // `child_frame_sink_id`, since all frame production/input processing uses the
  // oldest embedding. To be called by non-root CompositorFrameSinks only.
  FrameSinkId GetOldestParentByChildFrameId(
      const FrameSinkId& child_frame_sink_id) const;
  int GetNumParents(const FrameSinkId& frame_sink_id) const;
  // Returns the oldest RootCompositorFrameSink's FrameSinkId associated with
  // `child_frame_sink_id`, since all frame production/input processing uses
  // the oldest embedding.
  // In case `child_frame_sink_id` is not attached to a RootCompositorFrameSink
  // FrameSink(0,0) is returned.
  FrameSinkId GetOldestRootCompositorFrameSinkId(
      const FrameSinkId& child_frame_sink_id) const;

  // Returns children of a FrameSink that has |parent_frame_sink_id|.
  // Returns an empty set if a parent doesn't have any children.
  base::flat_set<FrameSinkId> GetChildrenByParent(
      const FrameSinkId& parent_frame_sink_id) const;
  CompositorFrameSinkSupport* GetFrameSinkForId(
      const FrameSinkId& frame_sink_id) const;

  // This cancels pending output requests owned by the frame sinks associated
  // with the specified BeginFrameSource.
  // The requets callback will be fired as part of request destruction.
  // This may be used in case we know a frame can't be produced any time soon,
  // so there's no point for caller to wait for the copy of output.
  void DiscardPendingCopyOfOutputRequests(const BeginFrameSource* source);

  // Called when video capture starts on the target frame sink with |id|.
  void OnCaptureStarted(const FrameSinkId& id);
  // Called when video capture stops on the target frame sink with |id|.
  void OnCaptureStopped(const FrameSinkId& id);

  // Invokes the callback with `true` if thread IDs do belong to neither this
  // process nor the host (i.e. browser) process. Invokes the callback with
  // `false` otherwise, or on any unexpected errors. Only implemented on
  // Android.
  void VerifySandboxedThreadIds(
      const base::flat_set<base::PlatformThreadId>& thread_ids,
      base::OnceCallback<void(bool)> verification_callback);

  // Manages transferring ownership of SurfaceAnimationManager for
  // cross-document navigations where a transition could be initiated on one
  // CompositorFrameSink but animations are executed on a different
  // CompositorFrameSink.
  void CacheSurfaceAnimationManager(
      const blink::ViewTransitionToken& transition_token,
      std::unique_ptr<SurfaceAnimationManager> manager);
  std::unique_ptr<SurfaceAnimationManager> TakeSurfaceAnimationManager(
      const blink::ViewTransitionToken& transition_token);
  // Returns true if an entry for this token was erased.
  bool ClearSurfaceAnimationManager(
      const blink::ViewTransitionToken& transition_token);

  FrameCounter* frame_counter() {
    return frame_counter_ ? &frame_counter_.value() : nullptr;
  }

  // Sends `copy_output_result` tagged by `destination_token` back to
  // `mojom::FrameSinkManagerClient`.
  void OnScreenshotCaptured(
      const blink::SameDocNavigationScreenshotDestinationToken&
          destination_token,
      std::unique_ptr<CopyOutputResult> copy_output_result);

  bool IsFrameSinkIdInRootSinkMap(const FrameSinkId& frame_sink_id);

  base::WeakPtr<FrameSinkManagerImpl> GetWeakPtr() {
    return weak_factory_.GetWeakPtr();
  }

  // Note that if context is lost, this shared image interface will become
  // invalid. Next call to this function will create a new interface.
  // It is up to the client to detect changes in the shared image interface.
  // This call is only valid after BindAndSetClient().
  gpu::SharedImageInterface* GetSharedImageInterface();

  ReservedResourceIdTracker* reserved_resource_id_tracker() {
    return &reserved_resource_id_tracker_;
  }

  const gfx::Size& copy_output_request_result_size_for_testing() const {
    return copy_output_request_result_size_for_testing_;
  }

  void RequestBeginFrameForGpuService(bool toggle);

  GpuServiceImpl* GetGpuService();

 private:
  friend class FrameSinkManagerTest;
  friend class CompositorFrameSinkSupportTestBase;
  friend class FlingSchedulerTest;

  // Metadata for a CompositorFrameSink.
  struct FrameSinkData {
    explicit FrameSinkData(bool report_activation);

    FrameSinkData(const FrameSinkData&) = delete;
    FrameSinkData& operator=(const FrameSinkData&) = delete;

    FrameSinkData(FrameSinkData&& other);
    FrameSinkData& operator=(FrameSinkData&& other);

    ~FrameSinkData();

    // A label to identify frame sink.
    std::string debug_label;

    // Indicates whether the client wishes to receive FirstSurfaceActivation
    // notification.
    bool report_activation;
  };

  // BeginFrameSource routing information for a FrameSinkId.
  struct FrameSinkSourceMapping {
    FrameSinkSourceMapping();

    FrameSinkSourceMapping(const FrameSinkSourceMapping&) = delete;
    FrameSinkSourceMapping& operator=(const FrameSinkSourceMapping&) = delete;

    FrameSinkSourceMapping(FrameSinkSourceMapping&& other);
    FrameSinkSourceMapping& operator=(FrameSinkSourceMapping&& other);

    ~FrameSinkSourceMapping();

    // The currently assigned begin frame source for this client.
    raw_ptr<BeginFrameSource> source = nullptr;
    // This represents a dag of parent -> children mapping.
    base::flat_set<FrameSinkId> children;
    // The parent FrameSinkId for |this| FrameSink. Empty for
    // RootCompositorFrameSinks. This keeps track of multiple parents in order
    // of their registration, similar to BeginFrameSource ordering, allowing
    // updates to parent in single step and removing the requirement for
    // walks in the hierarchy tree.
    std::list<FrameSinkId> parent;
  };

  void RecursivelyAttachBeginFrameSource(const FrameSinkId& frame_sink_id,
                                         BeginFrameSource* source);
  void RecursivelyDetachBeginFrameSource(const FrameSinkId& frame_sink_id,
                                         BeginFrameSource* source);

  // FrameSinkVideoCapturerManager implementation:
  CapturableFrameSink* FindCapturableFrameSink(
      const VideoCaptureTarget& target) override;
  void OnCapturerConnectionLost(FrameSinkVideoCapturerImpl* capturer) override;

  // Returns true if |child framesink| is or has |search_frame_sink_id| as a
  // child.
  bool ChildContains(const FrameSinkId& child_frame_sink_id,
                     const FrameSinkId& search_frame_sink_id) const;

  // Updates throttling recursively on a frame sink specified by its |id|
  // and all its descendants to send BeginFrames at |interval|.
  void UpdateThrottlingRecursively(const FrameSinkId& id,
                                   base::TimeDelta interval);

  // Called when throttling needs to be updated. Some examples can trigger such
  // an update include: starting of video capturing requires throttling on the
  // frame sink being captured to be stopped; a frame sink hierarchical change
  // requires throttling on affected frame sinks to be started or stopped.
  void UpdateThrottling();

  // Clears throttling operation on the frame sink with |id| and all its
  // descendants.
  void ClearThrottling(const FrameSinkId& id);

  // Clears HitTestQuery stored for |frame_sink_id| in
  // `display_hit_test_query_` when `InputOnViz` flag is enabled.
  void MaybeEraseHitTestQuery(const FrameSinkId& frame_sink_id);
  void MaybeAddHitTestQuery(const FrameSinkId& frame_sink_id);

  // Provides an output surface for CreateRootCompositorFrameSink().
  const raw_ptr<OutputSurfaceProvider> output_surface_provider_;

  raw_ptr<GpuServiceImpl> gpu_service_ = nullptr;

  const raw_ptr<GmbVideoFramePoolContextProvider> gmb_context_provider_;

  SurfaceManager surface_manager_;

  // Must be created after and destroyed before |surface_manager_|.
  HitTestManager hit_test_manager_;

  // InputManager is created only when `kInputOnViz` (Android-only) flag is
  // enabled. This is a pointer for testing.
  std::unique_ptr<InputManager> input_manager_;

  // Restart id to generate unique begin frames across process restarts.  Used
  // for creating a BeginFrameSource for RootCompositorFrameSink.
  const uint32_t restart_id_;

  // Whether display scheduler should wait for all pipeline stages before draw.
  const bool run_all_compositor_stages_before_draw_;

  // Whether capture pipeline should emit log messages to webrtc log.
  const bool log_capture_pipeline_in_webrtc_;

  // This is viz-global instance of DebugRendererSettings.
  DebugRendererSettings debug_settings_;

  base::ProcessId host_process_id_;

  DisplayHitTestQueryMap display_hit_test_query_;

  // List of observers caring about updates to HitTest regions.
  base::ObserverList<HitTestRegionObserver> hit_test_region_observers_;

  // Performance hint session factory of this viz instance.
  const raw_ptr<HintSessionFactory> hint_session_factory_;

  // Contains registered frame sink ids, debug labels and synchronization
  // labels. Map entries will be created when frame sink is registered and
  // destroyed when frame sink is invalidated.
  base::flat_map<FrameSinkId, FrameSinkData> frame_sink_data_;

  // Set of BeginFrameSource along with associated FrameSinkIds. Any child
  // that is implicitly using this frame sink must be reachable by the
  // parent in the dag.
  base::flat_map<BeginFrameSource*, FrameSinkId> registered_sources_;

  // Store the BeginFrameSource of root compositor frame sink.
  raw_ptr<BeginFrameSource> root_begin_frame_source_ = nullptr;
  FrameSinkId root_frame_sink_id_;

  // Contains FrameSinkId hierarchy and BeginFrameSource mapping.
  base::flat_map<FrameSinkId, FrameSinkSourceMapping> frame_sink_source_map_;

  // CompositorFrameSinkSupports get added to this map on creation and removed
  // on destruction.
  base::flat_map<FrameSinkId,
                 raw_ptr<CompositorFrameSinkSupport, CtnExperimental>>
      support_map_;

  // [Root]CompositorFrameSinkImpls are owned in these maps.
  base::flat_map<FrameSinkId, std::unique_ptr<RootCompositorFrameSinkImpl>>
      root_sink_map_;
  base::flat_map<FrameSinkId, std::unique_ptr<CompositorFrameSinkImpl>>
      sink_map_;

  base::flat_map<FrameSinkBundleId, std::unique_ptr<FrameSinkBundleImpl>>
      bundle_map_;

  base::flat_set<std::unique_ptr<FrameSinkVideoCapturerImpl>,
                 base::UniquePtrComparator>
      video_capturers_;

  base::flat_map<blink::ViewTransitionToken,
                 std::unique_ptr<SurfaceAnimationManager>>
      transition_token_to_animation_manager_;

  // The ids of the frame sinks that are currently being captured.
  // These frame sinks should not be throttled.
  base::flat_set<FrameSinkId> captured_frame_sink_ids_;

  // Ids of the frame sinks that have been requested to throttle.
  std::vector<FrameSinkId> frame_sink_ids_to_throttle_;

  // The throttling interval which defines how often BeginFrames are sent for
  // frame sinks in `frame_sink_ids_to_throttle_`, if
  // `global_throttle_interval_` is unset or if this interval is longer than
  // `global_throttle_interval_`.
  base::TimeDelta throttle_interval_ = BeginFrameArgs::DefaultInterval();

  // If present, the throttling interval which defines the upper bound of how
  // often BeginFrames are sent for all current and future frame sinks.
  std::optional<base::TimeDelta> global_throttle_interval_ = std::nullopt;

#if BUILDFLAG(IS_ANDROID)
  base::flat_map<uint32_t, base::ScopedClosureRunner> cached_back_buffers_;
#endif

  SEQUENCE_CHECKER(sequence_checker_);

  // |video_detector_| is instantiated lazily in order to avoid overhead on
  // platforms that don't need video detection.
  std::unique_ptr<VideoDetector> video_detector_;

  scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
  mojo::Remote<mojom::FrameSinkManagerClient> client_remote_;
  // There are three states this can be in:
  //  1. Mojo client: |client_| will point to |client_remote_|, the Mojo client,
  //     and |ui_task_runner_| will not be used. Calls to OnFrameTokenChanged()
  //     will go through Mojo. This is the normal state.
  //  2. Local (directly connected) client, *with* task runner: |client_| will
  //     point to the client, |client_remote_| will not be bound to any remote
  //     client, and calls to OnFrameTokenChanged() will be PostTasked using
  //     |ui_task_runner_|. Used mostly for layout tests.
  //  3. Local (directly connected) client, *without* task runner: |client_|
  //     will point to the client, |client_remote_| will not be bound to any
  //     remote client and |ui_task_runner_| will be nullptr, and calls to
  //     OnFrameTokenChanged() will be directly called (without PostTask) on
  //     |client_|. Used for some unit tests.
  raw_ptr<mojom::FrameSinkManagerClient, DanglingUntriaged> client_ = nullptr;

  mojo::Receiver<mojom::FrameSinkManager> frame_sink_manager_receiver_{this};
  mojo::Receiver<mojom::FrameSinksMetricsRecorder> metrics_receiver_{this};
  mojo::Receiver<mojom::FrameSinkManagerTestApi> test_api_receiver_{this};

  base::ObserverList<FrameSinkObserver>::Unchecked observer_list_;

  // Counts frames for test.
  std::optional<FrameCounter> frame_counter_;

  raw_ptr<SharedImageInterfaceProvider> shared_image_interface_provider_ =
      nullptr;

  ReservedResourceIdTracker reserved_resource_id_tracker_;

  gfx::Size copy_output_request_result_size_for_testing_;

  base::WeakPtrFactory<FrameSinkManagerImpl> weak_factory_{this};
};

}  // namespace viz

#endif  // COMPONENTS_VIZ_SERVICE_FRAME_SINKS_FRAME_SINK_MANAGER_IMPL_H_