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
|
// Copyright 2017 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_COMMON_SURFACES_LOCAL_SURFACE_ID_H_
#define COMPONENTS_VIZ_COMMON_SURFACES_LOCAL_SURFACE_ID_H_
#include <inttypes.h>
#include <compare>
#include <iosfwd>
#include <limits>
#include <string>
#include "base/unguessable_token.h"
#include "components/viz/common/viz_common_export.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
namespace perfetto {
template <typename MessageType>
class TracedProto;
namespace protos::pbzero {
class LocalSurfaceId;
}
} // namespace perfetto
namespace viz {
namespace mojom {
class LocalSurfaceIdDataView;
}
class ParentLocalSurfaceIdAllocator;
class ChildLocalSurfaceIdAllocator;
constexpr uint32_t kInvalidParentSequenceNumber = 0;
constexpr uint32_t kInvalidChildSequenceNumber = 0;
constexpr uint32_t kInitialParentSequenceNumber = 1;
constexpr uint32_t kInitialChildSequenceNumber = 1;
constexpr uint32_t kMaxParentSequenceNumber =
std::numeric_limits<uint32_t>::max();
constexpr uint32_t kMaxChildSequenceNumber =
std::numeric_limits<uint32_t>::max();
// This struct is the part of SurfaceId that can be modified by the client.
// LocalSurfaceId uniquely identifies a surface among the surfaces created by a
// particular client. A SurfaceId, which is FrameSinkId+LocalSurfaceId, uniquely
// identifies a surface globally across all clients.
//
// LocalSurfaceId consists of:
//
// - parent_sequence_number: This part is incremented by the embedder of the
// client.
//
// - child_sequence_number: This part is incremented by the client itself.
//
// - embed_token: An UnguessableToken generated by the embedder. The purpose of
// this value is to make SurfaceIds unguessable, because FrameSinkIds and
// LocalSurfaceIds are otherwise predictable and clients might exploit this
// fact to embed surfaces they're not allowed to. This value is generated once
// by ParentLocalSurfaceIdAllocator and remains constant during the lifetime
// of the embedding, even if a new LocalSurfaceId is generated for the
// embedded client because of some change in its state (e.g. size,
// device scale factor, etc.), or for other reasons. If a client is
// re-parented, then the new parent allocates a new LocalSurfaceId, with a new
// embed token, and communicates that to the embedded client.
//
// The embedder uses ParentLocalSurfaceIdAllocator to generate LocalSurfaceIds
// for the embedee. If Surface Synchronization is on, the embedee uses
// ChildLocalSurfaceIdAllocator to generate LocalSurfaceIds for itself. If
// Surface Synchronization is off, the embedee also uses
// ParentLocalSurfaceIdAllocator, as the parent doesn't generate LocalSurfaceIds
// for the child.
class VIZ_COMMON_EXPORT LocalSurfaceId {
public:
constexpr LocalSurfaceId()
: parent_sequence_number_(kInvalidParentSequenceNumber),
child_sequence_number_(kInvalidChildSequenceNumber) {}
constexpr LocalSurfaceId(const LocalSurfaceId& other) = default;
constexpr LocalSurfaceId& operator=(const LocalSurfaceId& other) = default;
constexpr LocalSurfaceId(uint32_t parent_sequence_number,
const base::UnguessableToken& embed_token)
: parent_sequence_number_(parent_sequence_number),
child_sequence_number_(kInitialChildSequenceNumber),
embed_token_(embed_token) {}
constexpr LocalSurfaceId(uint32_t parent_sequence_number,
uint32_t child_sequence_number,
const base::UnguessableToken& embed_token)
: parent_sequence_number_(parent_sequence_number),
child_sequence_number_(child_sequence_number),
embed_token_(embed_token) {}
static constexpr LocalSurfaceId MaxSequenceId() {
return LocalSurfaceId(kMaxParentSequenceNumber, kMaxChildSequenceNumber,
base::UnguessableToken());
}
constexpr bool is_valid() const {
return parent_sequence_number_ != kInvalidParentSequenceNumber &&
child_sequence_number_ != kInvalidChildSequenceNumber &&
!embed_token_.is_empty();
}
constexpr uint32_t parent_sequence_number() const {
return parent_sequence_number_;
}
constexpr uint32_t child_sequence_number() const {
return child_sequence_number_;
}
constexpr const base::UnguessableToken& embed_token() const {
return embed_token_;
}
// The |embed_trace_id| is used as the id for trace events associated with
// embedding this LocalSurfaceId.
uint64_t embed_trace_id() const { return persistent_hash() << 1; }
// The |submission_trace_id| is used as the id for trace events associated
// with submission of a CompositorFrame to a surface with this LocalSurfaceId.
uint64_t submission_trace_id() const { return (persistent_hash() << 1) | 1; }
friend std::strong_ordering operator<=>(const LocalSurfaceId&,
const LocalSurfaceId&) = default;
// This implementation is fast and appropriate for a hash table lookup.
// However the hash differs per process, and is inappropriate for tracing.
size_t hash() const;
// This implementation is slow and not appropriate for a hash table lookup.
// However the hash is consistent across processes and can be used for
// tracing.
size_t persistent_hash() const;
std::string ToString() const;
// Returns whether this LocalSurfaceId was generated after |other|. In the
// case where both `this` and `other` have advanced separate sequences, then
// this will return false.
bool IsNewerThan(const LocalSurfaceId& other) const;
// Returns whether this LocalSurfaceId was generated after |other|. In the
// case where both `this` and `other` have advanced separate sequences, then
// this will return false. In the case where `embed_token_` has changed, this
// will return true.
bool IsNewerThanOrEmbeddingChanged(const LocalSurfaceId& other) const;
// Returns whether this LocalSurfaceId was generated after |other| or equal to
// it.
bool IsSameOrNewerThan(const LocalSurfaceId& other) const;
// Returns the smallest valid LocalSurfaceId with the same embed token as this
// LocalSurfaceID.
LocalSurfaceId ToSmallestId() const;
using TraceProto = perfetto::protos::pbzero::LocalSurfaceId;
void WriteIntoTrace(perfetto::TracedProto<TraceProto> proto) const;
private:
friend struct mojo::StructTraits<mojom::LocalSurfaceIdDataView,
LocalSurfaceId>;
friend class ParentLocalSurfaceIdAllocator;
friend class ChildLocalSurfaceIdAllocator;
uint32_t parent_sequence_number_;
uint32_t child_sequence_number_;
base::UnguessableToken embed_token_;
};
VIZ_COMMON_EXPORT std::ostream& operator<<(
std::ostream& out,
const LocalSurfaceId& local_surface_id);
} // namespace viz
#endif // COMPONENTS_VIZ_COMMON_SURFACES_LOCAL_SURFACE_ID_H_
|