File: surface_allocation_group.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 (191 lines) | stat: -rw-r--r-- 8,337 bytes parent folder | download | duplicates (9)
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
// Copyright 2019 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_SURFACES_SURFACE_ALLOCATION_GROUP_H_
#define COMPONENTS_VIZ_SERVICE_SURFACES_SURFACE_ALLOCATION_GROUP_H_

#include <vector>

#include "base/containers/flat_set.h"
#include "base/memory/raw_ptr.h"
#include "base/unguessable_token.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/common/surfaces/surface_range.h"
#include "components/viz/service/viz_service_export.h"
#include "ui/latency/latency_info.h"

namespace viz {

class Surface;
class SurfaceManager;

// This class keeps track of the LocalSurfaceIds that were generated using the
// same ParentLocalSurfaceIdAllocator (i.e. have the same embed token).
// A SurfaceAllocationGroup is created when:
// - A surface is created with an embed token that was never seen before, OR
// - A surface embeds another surface that has an embed token that was never
//   seen before.
// Once all the surfaces in the allocation group and all of the embedders are
// unregistered, the allocation group will be garbage-collected.
class VIZ_SERVICE_EXPORT SurfaceAllocationGroup {
 public:
  SurfaceAllocationGroup(SurfaceManager* surface_manager,
                         const FrameSinkId& submitter,
                         const base::UnguessableToken& embed_token);

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

  ~SurfaceAllocationGroup();

  // Returns the ID of the FrameSink that is submitting to surfaces in this
  // allocation group.
  const FrameSinkId& submitter_frame_sink_id() const { return submitter_; }

  // Returns whether this SurfaceAllocationGroup can be destroyed by the garbage
  // collector; that is, there are no surfaces left in this allocation group and
  // there are no registered embedders.
  bool IsReadyToDestroy() const;

  // Called by |surface| at construction time to register itself in this
  // allocation group.
  void RegisterSurface(Surface* surface);

  // Called by |surface| at destruction time to unregister itself from this
  // allocation group.
  void UnregisterSurface(Surface* surface);

  // Called by |surface| when it has a pending frame that is blocked on
  // |activation_dependency| in this allocation group. The embedder will be
  // notified when |activation_dependency| becomes available.
  void RegisterBlockedEmbedder(Surface* surface,
                               const SurfaceId& activation_dependency);

  // Called by |surface| when its pending frame that still has an unresolved
  // activation dependency in this allocation group either activates
  // (|did_activate| == true) or gets dropped (|did_activate| == false).
  void UnregisterBlockedEmbedder(Surface* surface, bool did_activate);

  // Returns whether there is any embedder that is blocked on a surface in this
  // allocation group.
  bool HasBlockedEmbedder() const;

  // Called by |surface| when its newly activated frame references a surface in
  // this allocation group. The embedder will be notified whenever a surface in
  // this allocation group activates for the first time.
  void RegisterActiveEmbedder(Surface* surface);

  // Called by |surface| when it no longer has an active frame that references a
  // surface in this allocation group.
  void UnregisterActiveEmbedder(Surface* surface);

  // Notifies that a surface exists whose active frame references |surface_id|
  // in this allocation group. |surface_id| or the last surface prior to it may
  // be activated due to deadline inheritance.
  void UpdateLastActiveReferenceAndMaybeActivate(const SurfaceId& surface_id);

  // Notifies that a surface exists whose pending frame references |surface_id|
  // in this allocation group. |surface_id| or some surface prior to it might
  // activate if it was blocked due to child throttling.
  void UpdateLastPendingReferenceAndMaybeActivate(const SurfaceId& surface_id);

  // Returns the last SurfaceId in this allocation group that was ever
  // referenced by the active frame of a surface.
  const SurfaceId& GetLastActiveReference();

  // Returns the last SurfaceId in this allocation group that was ever
  // referenced by a pending or an active frame of a surface.
  const SurfaceId& GetLastReference();

  // Returns the latest active surface in the given range that is a part of this
  // allocation group. The embed token of at least one end of the range must
  // match the embed token of this group.
  Surface* FindLatestActiveSurfaceInRange(const SurfaceRange& range) const;

  // Takes the LatencyInfo of the active frame of |surface|, plus the
  // LatencyInfo of both pending and active frames of every surface older than
  // |surface|.
  void TakeAggregatedLatencyInfoUpTo(Surface* surface,
                                     std::vector<ui::LatencyInfo>* out);

  // Called by the surfaces in this allocation when they activate for the first
  // time.
  void OnFirstSurfaceActivation(Surface* surface);

  // Called when there will not be any calls to RegisterSurface in the future.
  // All pending embedders that were blocked on surfaces that don't exist yet
  // will have their dependency resolved.
  void WillNotRegisterNewSurfaces();

  // Called by surfaces which are blocked by this allocation group. This will
  // send an Ack to the latest active surface, if it has an un-Acked frame.
  void AckLastestActiveUnAckedFrame();

  // Returns the last surface created in this allocation group.
  Surface* last_created_surface() const {
    return surfaces_.empty() ? nullptr : surfaces_.back();
  }

  const std::vector<raw_ptr<Surface, VectorExperimental>>& surfaces() const {
    return surfaces_;
  }

 private:
  // Returns an iterator to the latest surface in |surfaces_| whose SurfaceId is
  // older than or equal to |surface_id|. The returned surface may not be active
  // yet.
  std::vector<raw_ptr<Surface, VectorExperimental>>::const_iterator
  FindLatestSurfaceUpTo(const SurfaceId& surface_id) const;

  // Returns an iterator to the latest active surface in |surfaces_| whose
  // SurfaceId is older than or equal to |surface_id|.
  std::vector<raw_ptr<Surface, VectorExperimental>>::const_iterator
  FindLatestActiveSurfaceUpTo(const SurfaceId& surface_id) const;

  // Notifies SurfaceManager if this allocation group is ready for destruction
  // (see IsReadyToDestroy() for the requirements).
  void MaybeMarkForDestruction();

  // Updates the last reference. |surface_id| or a surface prior to it might
  // activate if it was blocked due to child throttling.
  void UpdateLastReferenceAndMaybeActivate(const SurfaceId& surface_id);

  // The ID of the FrameSink that is submitting to the surfaces in this
  // allocation group.
  const FrameSinkId submitter_;

  // The embed token that the ParentLocalSurfaceIdAllocator used to allocate
  // LocalSurfaceIds for the surfaces in this allocation group. All the surfaces
  // in this allocation group use this embed token.
  const base::UnguessableToken embed_token_;

  // The list of surfaces in this allocation group in the order of creation. The
  // parent and child sequence numbers of these surfaces is monotonically
  // increasing.
  std::vector<raw_ptr<Surface, VectorExperimental>> surfaces_;

  // A map from the surfaces that have an unresolved activation dependency in
  // this allocation group, to the said activation dependency.
  base::flat_map<Surface*, SurfaceId> blocked_embedders_;

  // The set of surfaces that reference a surface in this allocation group by
  // their active frame.
  base::flat_set<raw_ptr<Surface, CtnExperimental>> active_embedders_;

  // We keep a pointer to SurfaceManager so we can signal when this object is
  // ready to be destroyed.
  const raw_ptr<SurfaceManager> surface_manager_;

  // The last SurfaceId of this allocation group that was ever referenced by the
  // active frame of a surface.
  SurfaceId last_active_reference_;

  // The last SurfaceId of this allocation group that was ever referenced by the
  // active or pending frame of a surface.
  SurfaceId last_reference_;
};

}  // namespace viz

#endif  // COMPONENTS_VIZ_SERVICE_SURFACES_SURFACE_ALLOCATION_GROUP_H_