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_
|